我想我错过了一个单元素列表的情况,但我找不到可以帮助我的方法来编写它?
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
答案 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 = []