繁体   English   中英

Haskell函数组成-错误地推断类型

[英]Haskell function composition - wrongly inferred type

在以下Haskell代码中,函数typeError不进行类型检查。

wrap x = [x]

listf :: [[a]] -> [[a]]
listf = id

typeCheck :: [a] -> [[a]]
typeCheck x = listf (wrap x)

typeError :: [a] -> [[a]]
typeError = wrap . listf

如果未注释,GHC会产生此错误:

Couldn't match type `a' with `[a0]'
  `a' is a rigid type variable bound by
      the type signature for typeError :: [a] -> [[a]] at tim.hs:10:1
Expected type: [a] -> [a]
  Actual type: [[a0]] -> [[a0]]
In the second argument of `(.)', namely `listf'
In the expression: wrap . listf

我不明白为什么。 a应该能够与[a0]统一-它们是独立的类型变量。 这正是它为typeCheck推断的类型-但不是. 使用运算符。

拥抱会产生非常相似且类似虚假的错误消息:

ERROR "repro.hs":10 - Inferred type is not general enough
*** Expression    : typeError
*** Expected type : [a] -> [[a]]
*** Inferred type : [[a]] -> [[[a]]]

此外,这很好用:

listf' :: [a] -> [a]
listf' = id

typeCheck' :: [a] -> [[a]]
typeCheck' = wrap . listf'

仅使用[[a]]或[[[a]]]或更高版本会出现此问题。 怎么了

您似乎在这里颠倒了功能组成。

-- This
typeCheck :: [a] -> [[a]]
typeCheck x = listf (wrap x)

-- is the same as
typeCheck' :: [a] -> [[a]]
typeCheck' = listf . wrap

-- while this
typeError :: [a] -> [[a]]
typeError = wrap . listf

-- is the same as
typeError' :: [a] -> [[a]] 
typeError' x = wrap (listf x)

现在希望这很明显为什么不起作用。 listf要求其参数为[[a]] ,但是typeError的签名声称它适用于任何[a]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM