Haskell - 有一个函数返回一个空字符

时间:2016-04-11 16:41:13

标签: haskell functional-programming

我正在尝试创建一个从字符串中删除每个第n个元素的函数。

dropEvery :: String -> Int -> String
dropEvery str n = map (\(char, indx) -> if indx `mod` n /= 0 then char else ' ') (zip str [1..])

现在它只是用空格替换每个第n个元素,但如果我希望它返回“空字符”,我应该在“else”之后放置什么。我知道在Haskell中不存在这样的事情,所以问题是 - 我怎么能告诉Haskell不返回任何东西而只是转到下一个字符?

3 个答案:

答案 0 :(得分:7)

您不能仅使用map来执行此操作,根据定义,它无法更改应用它的集合的长度。但是,通过切换到concatMap,您无需进行太多更改即可实现此功能。此函数需要您正在映射的函数返回一个列表,然后将所有结果连接在一起。所有你需要做的是

dropEvery str n =
    concatMap (\(char, indx) -> if indx `mod` n /= 0 then [char] else []) (zip str [1..])

答案 1 :(得分:5)

MainActivity保留列表的结构,而您的操作通过删除元素来修改它。这意味着您无法使用map,但您可以使用map,它允许您为要从输出中删除的元素提供返回mapMaybe的函数:

Nothing

答案 2 :(得分:3)

您可以在不mod的情况下执行此操作。我要翻转参数的顺序,使其更加惯用。

dropEvery :: Int -> [a] -> [a]
dropEvery n xs = map fst . filter ((/= n) . snd) $ zip xs (cycle [1..n])

如果速度至关重要,那么将此技术用于显式递归或foldr可能是最有效的。像这样:

dropEvery n xs = foldr go (`seq` []) xs n where
  go _ r 1 = r n
  go x r k = x : r (k - 1)