我很新的哈斯克尔,和我想以下几点:要获得[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]]那时我有一个非详尽的模式函数.
你很亲密.事实上,你想要的是某种"安全"的头脑.
列表[a]有两个构造函数:
[],你在第一种情况下覆盖这个; 和(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)