返回列表列表([[a]])但不使用空列表([]:[a])的语法(如果可能的话)是什么?(类似于下面第二个评论的后卫(2),这是不正确的)
这是一个正常工作的功能:
-- Split string on every (shouldSplit == true)
splitWith :: (Char -> Bool) -> [Char] -> [[Char]]
splitWith shouldSplit list = filter (not.null) -- would like to get rid of filter
(imp' shouldSplit list)
where
imp' _ [] = [[]]
imp' shouldSplit (x:xs)
| shouldSplit x = []:imp' shouldSplit xs -- (1) this line is adding empty lists
-- | shouldSplit x = [imp' shouldSplit xs] -- (2) if this would be correct, no filter needed
| otherwise = let (z:zs) = imp' shouldSplit xs in (x:z):zs
这是正确的结果
Prelude> splitWith (== 'a') "miraaaakojajeja234"
["mir","koj","jej","234"]
但是,它必须使用“过滤器”来清理其结果,所以我想摆脱“过滤器”功能。这是不使用过滤器的结果:
["mir","","","","koj","jej","234"]
如果使用“ | shouldSplit x = imp' shouldSplit xs ”代替第一个保护,则结果不正确:
["mirkojjej234"]
第一个守卫(1)添加空列表,因此(我假设)编译器可以将结果视为列表列表([[a]])。
(我对函数的另一个/不同解决方案不感兴趣,只是语法说明。)
.
.
.
答案:
Dave4420 的回答让我找到了答案,但这是一个评论,而不是一个答案,所以我不能接受它作为答案。问题的解决方案是我问错了问题。这不是语法的问题,而是我的算法的问题。
解决空列表问题的另一个/不同解决方案有几个答案,但它们不是我的问题的答案。然而,他们扩展了我对如何使用基本 Haskell 语法完成事情的方法的看法,我为此感谢他们。
编辑:
splitWith :: (Char -> Bool) -> String -> [String]
splitWith p = go False
where
go _ [] = [[]]
go lastEmpty (x:xs)
| p x = if lastEmpty then go True xs else []:go True xs
| otherwise = let (z:zs) = go False xs in (x:z):zs