【问题标题】:Non-exhaustive patterns in function haskell函数haskell中的非详尽模式
【发布时间】:2014-11-18 16:16:05
【问题描述】:
我想我错过了有一个元素列表但我找不到写它的方法有人可以帮助我的情况吗?
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
【问题讨论】:
标签:
haskell
non-exhaustive-patterns
【解决方案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
【解决方案2】:
首先,在您对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 = []