为什么1:[[]]等于(1:[]):[]?

时间:2017-12-15 16:01:33

标签: haskell list-comprehension

正如标题所说,我并没有完全理解哈斯克尔如何解释

1:[[]]

为什么它似乎(1:[]):[]

E:我得到了这个想法:

part'::[a] -> [[a]]
part' [] = [[]]
part' (x:xs) = p ++ [x:ys | ys <- p]
    where p = part' xs

具体来自p ++ [x:ys | ys <- p]

E.g。对于part'[1]:我的思路是否正确?:

part'[1] = (part'[]) ++ [1:ys | ys <- part'[]]
--> = [[]] ++ [1:[[]]]

希望这说清楚。

3 个答案:

答案 0 :(得分:8)

您似乎误解了[... | ys <- p]语法。在这种情况下,ys列表p的每个元素的替代,而不是整个列表。你问题的最后部分的等式推理应该是

part' [1] = (part' []) ++ [1:ys | ys <- p]
-- = [[]] ++ [1:ys | ys <- [[]]]
-- = [[]] ++ [1 : []]
-- = [[], [1]]

答案 1 :(得分:2)

Haskell中的[]可能会令人困惑。

空括号[]本身就是空列表的构造函数。通常这可以通过此备选(同构)列表定义来解释,其中[]称为Nil:称为Cons

data List a
  = Nil
  | Cons a (List a)

当您认为任何有限列表最终都有Nil时,事情就不会变得更加容易。它是结束递归的唯一可能方式,例如:

Cons 3 (Cons 4 (Cons 5 Nil))

或等同于:

3 : (4 : (5 : []))

这种方便的语法会产生一些混淆,它再次表达同样的含义:

[3, 4, 5]

现在,有人可能会将[]简单地称为empty list而不知道有关ConsNil的任何线索。

还有更多:在类型签名中,您会遇到[Int][a]这意味着List IntList a,因此括号 - 再次 - 表达完全不同的东西。

存在关于Haskell中括号含义的错误直觉的风险,突然之间你必须认真考虑[1][[1]]之类的事物的确切含义,或{ {1}}和1:[]

答案 2 :(得分:0)

看哪,列表:

[a,b,c] ++ [d,e,f] =
[a,b] ++ [c,d,e,f] =
[a] ++ [b,c,d,e,f] =
[] ++ [a,b,c,d,e,f] =
a : [b,c,d,e,f] =
a : b : [c,d,e,f] =
a : b : c : [d,e,f] =
a : b : c : d : [e,f] =
a : b : c : d : e : [f] =
a : b : c : d : e : f : [] =
[a,b,c,d,e,f] ++ [] =
[a,b,c,d,e] ++ [f] =
[a,b,c,d] ++ [e,f] =
[a,b,c] ++ [d,e,f] 

和列表推导:

[[a, 0] | a <- [1,2,3]] =
     [r | a <- [1,2,3], r <- [[a, 0]]] =
            concatMap (\a -> [[a, 0]]) [1,2,3] =
[[1, 0]] ++ [[2, 0]] ++ [[3, 0]] =
[[1, 0],     [2, 0],     [3, 0]]