Haskell 如何有条件地将元素插入列表?
假设我有一个字符串列表Haskell 如何有条件地将元素插入列表?,haskell,Haskell,假设我有一个字符串列表 ["hello", "xbox", "blue"] 现在我想在列表中“插入”(如创建一个新的不可变列表)换行字符,但前提是单词before以元音结尾,例如创建以下列表的函数: ["hello", "\n", "xbox", "blue", "\n"] 在haskell中,最优雅/直接的方法是什么?一种方法是使用do-符号do-列表单子上的符号非常类似于列表理解,但它也允许您“返回”多个元素。以下是我的实现: solution1 :: [String] -> [S
["hello", "xbox", "blue"]
现在我想在列表中“插入”(如创建一个新的不可变列表)换行字符,但前提是单词before以元音结尾,例如创建以下列表的函数:
["hello", "\n", "xbox", "blue", "\n"]
在haskell中,最优雅/直接的方法是什么?一种方法是使用
do
-符号do
-列表单子上的符号非常类似于列表理解,但它也允许您“返回”多个元素。以下是我的实现:
solution1 :: [String] -> [String]
solution1 strings = do
str <- strings -- Go through each element of the list
if last str `elem` "aeiou"
then [str, "\n"] -- 'Replace' that element with the element then a newline
else [str] -- Do nothing.
但实际上,它们做的基本相同-do
——列表上的符号基本上只是第二种方法的抽象
需要考虑的事项:我使用了
last
函数,但对于空字符串,这将失败。如何解决这个问题?在列表中使用递归:模式匹配,并检查第一个元素是否以元音结尾。我喜欢一元版本,但我猜它也比递归版本慢一点。。。嗯,你只需要使用case语句来防止空字符串,也许吧?@JohnSmith如果一元版本太低,我会感到惊讶。同样可以,您可以使用case
防止这种情况。然而,我可能倾向于在这一点上编写一个单独的函数。我更希望看到它是用foldr
编写的,并且它将公共x:
移动到if
之外,就像这样:foldr(\x acc->x:if last x`elem`“aeiou”然后“\n”:acc else acc)[/code>
solution2 :: [String] -> [String]
solution2 [] = [] -- Base case: empty list.
solution2 (x:xs) = -- Inductive case: non-empty list.
if last x `elem` "aeiou"
then x : "\n" : solution2 xs -- Recur, reconstructing as we go.
else x : solution2 xs -- Recur, this time with no extra newline.