在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
为什么会这样?
答案 0 :(得分:12)
由于monomorphism restriction,形式x = ...
(无参数)的定义被赋予单形(即非多态)类型,这通常涉及一些违约[{3}}。
要防止这种情况发生,请在定义中添加类型签名,或使用:set -XNoMonomorphismRestriction
禁用单态限制。您可以将其添加到in the other answer,以便在启动时自动运行.ghci
file。
答案 1 :(得分:4)
默认规则。
当您在GHCi中键入内容时,它会尝试应用默认类型。 IIRC,对于Num
约束的内容,它选择Integer
,Fractional
选择Double
,并选择其他所有内容()
。
如果你在Haskell源文件中写这个并加载到GHCi中,这不会发生(我相信)。
我认为您还可以说default Int
之类的内容,以便在每个模块的基础上更改默认规则。