函数中的非穷举模式具有优势

时间:2014-11-18 16:16:05

标签: haskell non-exhaustive-patterns

我想我错过了一个单元素列表的情况,但我找不到可以帮助我的方法来编写它?

getBoard :: [String] -> [String]
getBoard (h:t) | isLOL h = h: getBoard (t)
               | otherwise = []


isLOL :: String -> Bool
isLOL [ ] = True
isLOL (h:t) | h>='a' && h<='z' || h >='A' && h<='Z' = isLOL t
            | otherwise = False

2 个答案:

答案 0 :(得分:1)

getBoard [] = []

是您想要的行。像这样:

getBoard :: [String] -> [String]
getBoard [] = []
getBoard (h:t) | isLOL h = h: getBoard (t)
               | otherwise = []


isLOL :: String -> Bool
isLOL [] = True
isLOL (h:t) | h>='a' && h<='z' || h >='A' && h<='Z' = isLOL t
            | otherwise = False

答案 1 :(得分:1)

首先,在您对getBoard的定义中,问题是在模式(在您的情况下为|)之后检查了警卫(h:t之后的东西)是匹配。因此,如果getBoard的参数与h:t不匹配(即[]),则不会检查两个分支(包括otherwise分支)。解决方法是在[]上添加匹配项:

getBoard (h:t) | isLOL h = h : getBoard t
               | otherwise = []
getBoard [] = []

然而,与失败后卫的比赛会失败,所以你可以把它写成

getBoard (h:t) | isLOL h = h : getBoard t
getBoard _               = []

现在,关于如何以更好的方式编写此函数,使用Prelude中的递归方案:

isLOL可以改写为

isLOL = all $ \h -> 'a' <= h && h <= 'z' || 'A' <= h && h<= 'Z'

getBoard可以类似地重写,注意如果每个字符isLOL它将始终返回原始列表,否则返回空列表:

getBoard cs | all isLOL cs = cs
            | otherwise = []