【问题标题】:Why does this function take an [[a]]?为什么这个函数需要一个 [[a]]?
【发布时间】:2015-09-23 06:01:08
【问题描述】:

我正在编写 Haskell 代码练习尾递归来反转一个列表,并提出了这个解决方案:

reverseh' [] list = list
reverseh' (x:xs) list = reverseh' (xs) (x ++ list)
reverse' x = reverseh' x []

它仅适用于列表列表,但我希望它具有类型签名 [a] -> [a]

你能解释一下我在这里做错了什么吗?

【问题讨论】:

  • 我有同样的问题,你的问题帮助我找到了解决方案

标签: haskell type-inference type-systems


【解决方案1】:

如果你没有得到预期的类型,最好添加一个显式的类型签名来告诉编译器你想要的类型是什么,这里:

reverseh' :: [a] -> [a] -> [a]

然后你得到一个编译错误:

Couldn't match expected type `[a]' with actual type `a'     
  `a' is a rigid type variable bound by                     
      the type signature for reverseh' :: [a] -> [a] -> [a] 
      at reverseh.hs:1:14                                   
Relevant bindings include                                   
  list :: [a] (bound at reverseh.hs:3:18)                   
  xs :: [a] (bound at reverseh.hs:3:14)                     
  x :: a (bound at reverseh.hs:3:12)                        
  reverseh' :: [a] -> [a] -> [a] (bound at reverseh.hs:2:1) 
In the first argument of `(++)', namely `x'                 
In the second argument of reverseh', namely `(x ++ list)'   

这告诉您,在(x ++ list) 中,x 必须是 [a] 类型才能进行类型检查,但考虑到您所考虑的类型签名,x 确实是 a 类型。所以你想用a -> [a] -> [a]类型的函数替换++,所以你用(x : list)

【讨论】:

    【解决方案2】:

    由于第二行中的(x ++ list) 表达式,typechecker 认为x :: [a]。我猜你想写(x : list)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-18
      • 2012-02-13
      • 2021-05-05
      相关资源
      最近更新 更多