7

玩弄ghci我得到以下表达式:unlines . map (\(a,b) -> show a ++ " " ++ show b)

现在,当我通过它检查时,:t我得到:

> :t  unlines . map (\(a,b) -> show a ++ " " ++ show b)
unlines . map (\(a,b) -> show a ++ " " ++ show b)
  :: (Show a, Show a1) => [(a, a1)] -> String

所以完全符合预期。但是现在,如果我尝试将其分配给某个名称,我会得到一个比原始签名更具体的签名:

> let f = unlines . map (\(a,b) -> show a ++ " " ++ show b)
> :t f
f :: [((), ())] -> String

为什么会这样?

4

2 回答 2

12

由于单态限制,形式x = ...(无参数)的定义被赋予单态(即非多态)类型,这通常涉及其他答案中提到的一些默认值。

为防止这种情况发生,请在定义中添加类型签名,或使用:set -XNoMonomorphismRestriction. 你可以把它添加到你的.ghci文件中,让它在启动时自动运行,直到它在未来版本的 GHCi 中被默认禁用

于 2013-03-16T16:38:18.733 回答
4

违约规则。

当您在 GHCi 中键入内容时,它会尝试应用默认类型。IIRC,对于它选择的有Num约束的东西Integer,对于Fractional它选择Double的东西,以及它选择的所有其他东西()

如果您将其写入 Haskell 源文件并将其加载到 GHCi 中,则不会发生这种情况(我相信)。

我想你也可以说像default Int在每个模块的基础上更改默认规则。

于 2013-03-16T16:14:52.447 回答