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

考虑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: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"