作为Haskell中的(@)模式

Spe*_*ela 4 haskell

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.

Ian*_*nry 9

看这里:

lst == [] = []
Run Code Online (Sandbox Code Playgroud)

lst永远不能等于[],因为你这么说lst = hd:tl.相反,你可以打破那个分支,进入一个独立的模式匹配,以获得完全覆盖.(Eq一旦你这样做,你也可以放弃约束.)

当你调用时take' 20 [],它会尝试找到一个与之匹配的模式,但是你没有写一个:hd:tl无法匹配[].在模式无法匹配之后,它不会看到该模式的守卫.