【发布时间】:2021-03-28 15:20:48
【问题描述】:
我编写了函数fun1,它接受一个列表并删除每个大于或等于先前数字的数字。
fun1 (l:ls) =
fun' [l] ls
where
fun' a z =
case z of
[] -> a
_ -> fun' (if (head z) < (last a) then a ++ [head z] else a) (tail z)
效果很好:
> fun1 [4,4,5,9,7,4,3,1,2,0]
=> [4,3,1,0]
在最后一行而不是使用head z 和tail z 我想使用z@(x:xs) 这是我曾经见过的语法糖。
我在fun2 中尝试过,但出现非详尽模式错误。
当我使用case xs of 而不是case z of 时,该函数运行而不会引发错误,但是这样它要么会跳过最后一个元素,要么我将不得不编写操作以再次应用于最后一个元素(我显然不会想做)。
fun2 (l:ls) =
fun' [l] ls
where
fun' a z@(x:xs) =
case z of -- "case xs of" would work, but will skip the last element
[] -> a
_ -> fun' (if x < (last a) then a ++ [x] else a) xs
这会导致非详尽模式错误:
> fun2 [4,4,5,9,7,4,3,1,2,0]
*** Exception: main.hs:(4,5)-(7,61): Non-exhaustive patterns in function fun'
当我尝试匹配z 的模式时,为什么会出现此错误?
【问题讨论】:
-
fun1未为非空列表定义(fun2也未定义。 -
是的,但假设一个人只会调用
fun1和fun2并使用非空列表仍然问题出在fun',或者我错过了什么?当然我可以添加fun1 [] = [],但这并不能解决我的问题。 -
fun'也一样:你只在第二个参数非空时才定义这个,所以case z没有意义:你在(x:xs)上进行模式匹配 -
是的:如果所有子模式也匹配,则该模式将“触发”。
-
像这样反复使用
last和++ [foo]很昂贵。而是直接开始发射值,如fun1 (l:ls) = fun' l ls where fun' a [] = []; fun' a (x:xs) = if x < a then x : fun' x xs else fun' a xs。