Haskell 需要在两个单独的函数调用中等效的类型
考虑Haskell中的以下两个函数(我的实际代码的一个最小示例): 第一个编译很好,但第二个生成错误:Haskell 需要在两个单独的函数调用中等效的类型,haskell,types,ghci,type-systems,Haskell,Types,Ghci,Type Systems,考虑Haskell中的以下两个函数(我的实际代码的一个最小示例): 第一个编译很好,但第二个生成错误: Could not deduce (a ~ b) from the context (Show a, Show b) bound by the type signature for printSequence' :: (Show a, Show b) => a -> b -> IO () at test.hs
Could not deduce (a ~ b)
from the context (Show a, Show b)
bound by the type signature for
printSequence' :: (Show a, Show b) => a -> b -> IO ()
at test.hs:8:19-53
`a' is a rigid type variable bound by
the type signature for
printSequence' :: (Show a, Show b) => a -> b -> IO ()
at test.hs:8:19
`b' is a rigid type variable bound by
the type signature for
printSequence' :: (Show a, Show b) => a -> b -> IO ()
at test.hs:8:19
In the first argument of print', namely `y'
In the second argument of `(>>)', namely `(print' y)'
In the expression: (print' x) >> (print' y)
我理解此错误意味着GHC要求
x
和y
为等效类型。我不明白的是为什么。像print“fish”>>print 3.14
这样的语句在解释器中工作得非常好,那么当我两次调用我的print'
函数时,GHC为什么抱怨x
和y
是不同的类型呢?添加一个明确的类型签名:
printSequence' :: (Show a, Show b) => a -> b -> IO ()
printSequence' x y = print' x >> print' y
where
print' :: Show a => a -> IO ()
print' = putStr . show
或使用:
那么
这在逐字复制时有效,但我有一个关于您的第一个解决方案的后续问题。为什么当我在同一行中提供类型签名时失败,比如
where print'=(putStr.show)::show a=>a->IO()
?@ApproachingDarknessFish在=符号的右侧注释值,让GHC在左侧推断名称的类型。GHC为没有显式函数参数的模式推断单态类型,并且在右侧声明多态类型不会改变该规则。关于可怕的单态限制:
printSequence' :: (Show a, Show b) => a -> b -> IO ()
printSequence' x y = print' x >> print' y
where
print' :: Show a => a -> IO ()
print' = putStr . show
{-# LANGUAGE NoMonomorphismRestriction #-}
printSequence' :: (Show a, Show b) => a -> b -> IO ()
printSequence' x y = print' x >> print' y
where
print' = putStr . show
\> printSequence' 5 "five"
5"five"