我想在换行符上拆分一个字符串,我很惊讶我找不到intercalate "\n"
的反函数。也就是说,一个函数将字符串拆分成新行(或根据其他谓词)。
请注意lines
和words
做了不同的事情。例如
intercalate "\n" (lines "a\n") == "a"
split 库中有一个类似的函数函数splitOn
。我也可以直接自己编写这样的函数:
splitOn :: (a -> Bool) -> [a] -> [[a]]
splitOn p = map reverse . g []
where
g rs [] = [rs]
g rs (x:xs) | p x = rs : g [] xs
| otherwise = g (x : rs) xs
但我想知道是否只使用base中的函数可以更轻松地构建它。
答案 0 :(得分:5)
如果您正在寻找更原始函数的组合,那么除了基于unfoldr
和break
的内容之外我别无其他想法,但unfoldr
不是在Prelude
。
无论如何,我认为你很清楚Prelude
远非我们许多人想要的那样,所以毫无疑问它甚至无法解决这个看似微不足道的问题。 Prelude
的一般问题似乎是错误的:该模块的目的是提供足以与Haskell一起玩的东西作为介绍的一部分,正如其名称所暗示的那样,但由于没有标准的“基础”模块,Haskellers倾向于将其视为一个。
答案 1 :(得分:5)
正如尼基塔·沃尔科夫指出的那样,限制“只有Prelude功能”并不容易,但这里有一个选择:
splitWhen p [] = [[]]
splitWhen p l = uncurry (:) . fmap (splitWhen p . drop 1) . break p $ l
这使用Functor
的{{1}}实例替代(,) a
(以避免凌乱的lambda表达式),它可以在不导入任何内容的情况下工作(ghci说“在GHC中定义”。 Base'“),但我不确定它是否真的属于Control.Arrow.second
,因为我在Haskell报告中找不到它。
编辑:允许使用Prelude
中的其他功能甚至不能帮助我。在任何情况下,我都会使用base
代替second
,因为我认为它会增加一些清晰度。使用fmap
,使用种子unfoldr
来区分字符串的结尾和空白部分(或示例中的空行):
Maybe