【问题标题】:Types required to be equivalent across two separate function calls需要在两个单独的函数调用中等效的类型
【发布时间】:2016-03-06 02:16:20
【问题描述】:

考虑 Haskell 中的以下两个函数(我的真实代码的最小示例):

printSequence :: (Show a, Show b) => a -> b -> IO ()
printSequence x y = (putStr . show) x >> (putStr . show) y

printSequence' :: (Show a, Show b) => a -> b -> IO ()
printSequence' x y = print' x >> print' y
    where print' = putStr . show

第一个编译正常,但第二个产生错误:

 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 要求 xy 是等效类型。我不明白的是为什么。 print "fish" >> print 3.14 这样的语句在解释器中工作得非常好,那么当我两次调用我的 print' 函数时,为什么 GHC 抱怨 xy 是不同的类型?

【问题讨论】:

标签: haskell types ghci type-systems


【解决方案1】:

添加显式类型签名:

printSequence' :: (Show a, Show b) => a -> b -> IO ()
printSequence' x y = print' x >> print' y
    where
    print' :: Show a => a -> IO ()
    print' = putStr . show

或使用NoMonomorphismRestriction:

{-# 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"

【讨论】:

  • 这在逐字复制时有效,但我有一个关于您的第一个解决方案的后续问题。为什么当我在同一行中提供类型签名时会失败,例如 where print' = (putStr . show) :: Show a => a -> IO ()
  • @ApproachingDarknessFish 注释 = 符号右侧的值,让 GHC 推断左侧名称的类型。 GHC 为没有显式函数参数的模式推断单态类型,并且在右侧声明多态类型不会改变该规则。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-25
  • 2017-10-19
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
相关资源
最近更新 更多