我有以下两个类似的函数定义:
left f (Left x) = Left (f x)
left _ (Right x) = Right x
left' f (Left x) = Left (f x)
left' _ r@(Right _) = r
当我检查这两个函数的类型签名时,我对以下类型感到困惑:
ghci> :t left
left :: (t -> a) -> Either t b -> Either a b
ghci> :t left'
left' :: (a -> a) -> Either a b -> Either a b
我想
left
和 left'
应该是相同的类型签名,但是 haskell 的类型推断给了我一个惊喜。我不知道为什么
left
的类型签名和 left'
是不同的。谁能给我一些信息?谢谢!
最佳答案
在 left'
的第二行:
left' _ r@(Right _) = r
-- ^^^^^^^^^^^ ^
由于您使用 as 模式,因此您需要输入类型等于返回类型,因为显然它们是完全相同的值。
left'
的类型然后被限制为 a -> b -> b
形式的东西。 .然后这个限制向后传播,反过来又限制了函数的类型——希望你能看到如何;这不是太难。
但是,在
left
的第二行中, 你构造了一个新值left _ (Right x) = Right x
-- ^^^^^^^
这个新值的类型没有被限制,因此不会出现同样的问题;它可以是
a -> b -> c
的形式,这就是你想要的。因此,
left'
的类型比 left
的类型更受限制,这就是导致它们的类型不相等的原因。为了更具体地说明这个概念,我将更准确地向您描述这种限制是如何向后传播的。
我们知道
left'
的签名格式为 (a -> b) -> Either a q -> Either b q
.但是,第 2 行规定 Either a q = Either b q
,这意味着 a = b
, 所以类型现在变成了 (a -> a) -> Either a q -> Either a q
.
关于haskell - 为什么在两个相似的函数定义中类型推断与 as-pattern 的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55432131/