5

我已经开始阅读 Thinking With Types 这本书,这是我第一次涉足类型级编程。作者提供了一个练习和解决方案,我无法理解提供的解决方案如何正确。

练习是

在此处输入图像描述

我试图用以下方法解决这个练习

productToRuleMine :: (b -> a, c -> a) -> Either b c -> a
productToRuleMine (f, _) (Left b) = f b
productToRuleMine (_, g) (Right c) = g c

productFromRuleMine :: (Either b c -> a) -> (b -> a, c -> a)
productFromRuleMine f = (f . Left, f . Right)

productToRuleMine . productFromRuleMine = id

我觉得这是一个有效的解决方案,但是这本书给出了一个不同的解决方案,似乎没有进行类型检查,这让我相信我的整体理解是有缺陷的

productToRuleBooks :: (b -> a) -> (c -> a) -> (Either b c) -> a
productToRuleBooks f _ (Left b) = f b
productToRuleBooks _ g (Right c) = g c

productFromRuleBooks :: (Either b c -> a) -> (b -> a, c -> a)
productFromRuleBooks f = (f . Left, f . Right)

我可以获得类型检查的书籍答案的唯一方法是:

(uncurry productToRule1 . productFromRule1) = id

因为单独的类型签名不排队

(Either b c -> a) -> (b -> a  ,   c -> a)
                     (b -> a) -> (c -> a) -> (Either b c) -> a

所以我的问题是,我的解决方案不正确吗?为什么书籍类型签名productToRuleBooks接受作为函数的第一个和第二个参数b -> ac -> a当我理解x (multiplication)代数等于(,)in 类型时,为什么书籍答案没有(b -> a, c -> a)作为第一个参数?

4

0 回答 0