是否有任何haskell函数可以将列表与分隔符连接起来?

Posted

技术标签:

【中文标题】是否有任何haskell函数可以将列表与分隔符连接起来?【英文标题】:Is there any haskell function to concatenate list with separator? 【发布时间】:2012-03-02 12:30:36 【问题描述】:

有没有用分隔符连接列表元素的功能? 例如:

> foobar " " ["is","there","such","a","function","?"]
["is there such a function ?"]

感谢您的回复!

【问题讨论】:

我知道 lmgtfy 的答案很糟糕,但值得注意的是,在 hoogle 上搜索“String -> [String] -> String”会得到你想要的。 haskell.org/hoogle 加入空间你也有unwords @sigfpe 旁注:你必须寻找[String] -> String -> String,以防其他方式返回没有答案,对吧? @LayGonzález 搜索取决于排列。例如,搜索 [a] -> (a -> b) -> [b] 会返回 map 作为其第一个结果。 【参考方案1】:

intersperse 和 intercalate 实现的其他一些想法,如果有人感兴趣的话:

myIntersperse :: a -> [a] -> [a]
myIntersperse _ [] = []
myIntersperse e xs = init $ xs >>= (:[e])

myIntercalate :: [a] -> [[a]] -> [a]
myIntercalate e xs = concat $ myIntersperse e xs

xs >>= f 等价于concat (map f xs)

【讨论】:

【参考方案2】:

是的,there is:

Prelude> import Data.List
Prelude Data.List> intercalate " " ["is","there","such","a","function","?"]
"is there such a function ?"

intersperse 更笼统一些:

Prelude> import Data.List
Prelude Data.List> concat (intersperse " " ["is","there","such","a","function","?"])
"is there such a function ?"

另外,对于你想加入空格字符的特定情况,有unwords

Prelude> unwords ["is","there","such","a","function","?"]
"is there such a function ?"

unlines 的工作方式类似,只是字符串使用换行符进行内爆,并且换行符也添加到末尾。 (这对于序列化文本文件很有用,根据 POSIX 标准,文本文件必须以尾随换行符结尾)

【讨论】:

它可以处理可能的空字符串吗? @CMCDragonkai 不确定您到底指的是什么,但是是的,这些函数都允许任意字符串作为分隔符和元素。例如,intercalate "," ["some", "", "string"] = "some,,string"intercalate "" ["foo", "bar"] = "foobar" unlines 每行加一个换行符,即unlines ["A", "B"] = "A\nB\n",所以和插层不一样。 @KathyVanStone 有趣,我想我从未尝试过,只是假设它的工作原理类似于 unwords 很高兴在标准库中有一些普通的字符串和列表操作函数,很高兴你在这里发布一个例子,因为很难找到这种日常的任何文档在 Haskell 中编程。【参考方案3】:

用 foldr 写单行字并不难

join sep xs = foldr (\a b-> a ++ if b=="" then b else sep ++ b) "" xs
join " " ["is","there","such","a","function","?"]

【讨论】:

为此添加描述会很有帮助;有人将其标记为低质量。【参考方案4】:

如果您想编写自己的 intercalateintersperse 版本:

intercalate :: [a] -> [[a]] -> [a]
intercalate s [] = []
intercalate s [x] = x
intercalate s (x:xs) = x ++ s ++ (intercalate s xs)

intersperse :: a -> [a] -> [a]
intersperse s [] = []
intersperse s [x] = [x]
intersperse s (x:xs) = x : s : (intersperse s xs)

【讨论】:

为什么要限制自己使用字符串?此外,您在函数应用程序周围的括号是多余的。 是的,intersperse 不必是Strings,但intercalate 至少需要是Show,如果你确实使用Show ,无论如何,您都需要使用Strings 来处理它们。我仍然习惯于 Haskell 如何处理混合的中缀和前缀函数/运算符,并且我更喜欢在混合时使用括号,以防我最终想要使用 $ intercalate :: [a] -> [[a]] -> [a] - 为什么是Show?至于语法,Haskell 没有任何前缀运算符(- 除外,这是一个可憎的),函数应用程序比任何中缀运算符绑定得更紧密:x:s:intersperse s xs 很好(但如果你把空格:x : s : intersperse s xs(我真的不明白为什么人们喜欢忽略:周围的空格)。 对。我一直忘记使用字符串只是使用列表。 Show 是因为我假设您希望结果是 String。我所说的“中缀和前缀函数/运算符”是指“前缀函数和中缀运算符”,但这并不清楚。一元 - 是死亡。至于:s 和其他中缀运算符,我是否使用空格很大程度上取决于上下文,但我总是局部一致。例如,模式匹配中的(:) 永远不会有空格,但在其他地方它取决于它是否被括号括起来以及我的心情。【参考方案5】:
joinBy sep cont = drop (length sep) $ concat $ map (\w -> sep ++ w) cont

【讨论】:

以上是关于是否有任何haskell函数可以将列表与分隔符连接起来?的主要内容,如果未能解决你的问题,请参考以下文章

Haskell中是否有“继续”?

在 Haskell 中即时减少列表

是否有任何 PHP 函数可以将数字转换为具有千位分隔符的货币?

Haskell 持久列表

是否有可能在haskell中有一套理解?

Haskell 中的并行“任何”或“全部”