列表中的Haskell列表

Dav*_*rez 2 haskell list

我很新的哈斯克尔,和我想以下几点:要获得[1,2,3][[1,2,3],[4,5,6]]

example :: [[a]] -> [a]
example [] = []
example [x:xs] = [x]
Run Code Online (Sandbox Code Playgroud)

这个例子[1]在输入时返回[[1,2,3]],如果我在主List中添加另一个元素,就像[[1,2,3],[3,4,5]]那时我有一个非详尽的模式函数.

Wil*_*sem 6

你很亲密.事实上,你想要的是某种"安全"的头脑.

列表[a]有两个构造函数:

  1. 空列表[],你在第一种情况下覆盖这个; 和
  2. "利弊" (x:xs).

看起来你在第二种情况下覆盖它,但事实上你没有:你把模式放在括号内.因此,Haskell将您的模式解释为[(x:xs)].所以它认为你匹配一个单例列表(一个元素的列表),这x是子列表的头部,以及子列表xs的尾部.

实际上你想掩盖(x:xs).如果我们使用这种模式,还有另一个问题:x是列表的头部,所以它有类型[a].因此,我们应该返回x,而不是[x],因为在后一种情况下,我们将子列表包装回列表中.

所以正确的功能是:

example :: [[a]] -> [a]
example [] = []
example (x:_) = x  -- round brackets, x instead of [x]
Run Code Online (Sandbox Code Playgroud)

请注意,由于我们对尾部不感兴趣,因此我们使用下划线_.如果你使用所有警告编译(-Wall或更具体-Wunused-matches),Haskell会抱怨你声明一个你不使用的变量.

推广到一个safeHead函数

我们可以将其概括为某种泛型safeHead :: b -> (a -> b) -> [a] -> b函数:

safeHead :: b -> (a -> b) -> [a] -> b
safeHead d _ [] = d
safeHead _ f (x:_) = f x
Run Code Online (Sandbox Code Playgroud)

因此,我们在这里传递三个参数safeHead:一个值(类型b)我们应该返回以防列表为空; 一个函数来处理头(类型a -> b)和列表到process.在这种情况下,example相当于:

example :: [[a]] -> [a]
example = safeHead [] id
Run Code Online (Sandbox Code Playgroud)

但我们也可以在Maybe [a]这里返回:

example2 :: [a] -> Maybe a
example2 = safeHead Nothing Just
Run Code Online (Sandbox Code Playgroud)