为什么签名在分配后会发生变化

时间:2013-03-16 16:12:00

标签: haskell ghci

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

为什么会这样?

2 个答案:

答案 0 :(得分:12)

由于monomorphism restriction,形式x = ...(无参数)的定义被赋予单形(即非多态)类型,这通常涉及一些违约[{3}}。

要防止这种情况发生,请在定义中添加类型签名,或使用:set -XNoMonomorphismRestriction禁用单态限制。您可以将其添加到in the other answer,以便在启动时自动运行.ghci file

答案 1 :(得分:4)

默认规则。

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

如果你在Haskell源文件中写这个并加载到GHCi中,这不会发生(我相信)。

我认为您还可以说default Int之类的内容,以便在每个模块的基础上更改默认规则。