为什么我的inits实现失败了?

时间:2018-01-24 00:08:49

标签: haskell

以下是我如何实施它:

inits' :: [a] -> [[a]]
inits' [] = [[]]
inits' xs = inits'(init xs) : xs

我收到此错误:

• Couldn't match type ‘a’ with ‘[[a]]’
  ‘a’ is a rigid type variable bound by
    the type signature for:
      inits' :: forall a. [a] -> [[a]]
  Expected type: [[[a]]]
    Actual type: [a]
• In the second argument of ‘(:)’, namely ‘xs’
  In the expression: inits' (init xs) : xs
  In an equation for ‘inits'’: inits' xs = inits' (init xs) : xs

似乎要生成inits,我必须在每个子列表上调用init。我做错了什么?

1 个答案:

答案 0 :(得分:3)

您似乎将此设计为

的镜像版本
tails' :: [a] -> [[a]]
tails' [] = [[]]
tails' xs = xs : tails' (tail xs)

有效的原因是:运算符会将单个元素xs添加到列表中。这也可以写成

tails' xs = [xs] ++ tails' (tail xs)

但是在inits'(init xs) : xs中,这不适用:单个元素将是inits'(init xs),但实际上它已经是嵌套列表。然而,++版本可以工作:

inits' xs = inits'(init xs) ++ [xs]

介意,这是非常低效的,因为++总是需要遍历整个LHS列表,这在递归中反复发生。