我已经开始阅读《用类型思考》这本书,这是我第一次尝试类型级编程。作者提供了一个练习和解决方案,我无法理解所提供的解决方案是如何正确的。
练习是
我尝试通过以下方法解决此问题
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
等于{{1时,为什么b -> a
的书类型签名会接受函数c -> a
和x (multiplication)
作为其第一和第二个参数}}的类型,那么为什么书中的答案没有以(,)
作为第一个参数?