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.