如何有条件地将元素插入列表?

时间:2019-04-20 13:04:46

标签: haskell

说我有一个字符串列表

["hello", "xbox", "blue"]

现在我要“插入”(如在创建新的不可变列表中一样)换行字符到列表中,但前提是前一个单词以元音结尾,例如创建以下列表的函数:

["hello", "\n", "xbox", "blue", "\n"]

在haskell中最优雅/最直接的方法是什么?

1 个答案:

答案 0 :(得分:3)

执行此操作的一种方法是使用do表示法。列表monad上的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.

但这是处理事情的一种怪异方法,特别是如果您是初学者。通常的方法是递归,所以让我们做一下:

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.

尽管实际上,它们的作用基本相同-列表上的do-标记基本上只是第二种方法的抽象。

要考虑的事情:我使用了last函数,但是这对于空字符串将失败。您该如何解决?