我take在Haskell中编写了自己的函数,如下所示:
take' :: (Integral n, Eq a) => n -> [a] -> [a]
take' n lst
| n <= 0 = []
| lst == [] = []
| otherwise = (head lst) : (take' (n-1) $ tail lst)
Run Code Online (Sandbox Code Playgroud)
而且运作良好.
但是当我尝试在函数参数中使用as(@)模式编写相同的函数时,似乎该函数无法识别第二个guard选项:
take' :: (Integral n, Eq a) => n -> [a] -> [a]
take' n lst@(hd:tl)
| n <= 0 = []
| lst == [] = []
| otherwise = hd : (take' (n-1) $ tl)
Run Code Online (Sandbox Code Playgroud)
当我尝试take' 20 []ghci时,我得到了Non-exhaustive patterns in function take'错误.
我究竟做错了什么?
谢谢,Špela.
看这里:
lst == [] = []
Run Code Online (Sandbox Code Playgroud)
lst永远不能等于[],因为你这么说lst = hd:tl.相反,你可以打破那个分支,进入一个独立的模式匹配,以获得完全覆盖.(Eq一旦你这样做,你也可以放弃约束.)
当你调用时take' 20 [],它会尝试找到一个与之匹配的模式,但是你没有写一个:hd:tl无法匹配[].在模式无法匹配之后,它不会看到该模式的守卫.