我已经开始阅读 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 -> a
,c -> a
当我理解x (multiplication)
代数等于(,)
in 类型时,为什么书籍答案没有(b -> a, c -> a)
作为第一个参数?