Haskell - have a function return an empty character

旧时模样 提交于 2019-12-23 09:32:25

问题


I'm trying to create a function that drops every n'th element from a string.

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

Right now it simply replaces every n'th element with a space, but what am I supposed to put after the "else" if I want it to return an "empty char". I understand that such a thing doesn't exist in Haskell so the question is - how am I supposed to tell Haskell to not return anything and just move on to the next char?


回答1:


You can't do this with just map, by definition it can't change the length of the collection it's applied to. However, you can get this to work without too many changes by switching to concatMap. This function requires the your function that you're mapping return a list, then it concatenates all the results together. All you'd need to do is

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



回答2:


map preserves the structure of the list, while your operations modifies it by removing elements. This means you can't use map, but you can use mapMaybe which allows you to provide a function which returns Nothing for elements you want to remove from the output:

import Data.Maybe (mapMaybe)
dropEvery str n = mapMaybe (\(char, indx) -> if indx `mod` n /= 0 then Just(char) else Nothing) (zip str [1..])



回答3:


You can do this without mod. I'm going to flip the order of the arguments to make this more idiomatic.

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

If speed is critical, it would likely be most efficient to use this technique with explicit recursion or foldr. Something like this:

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


来源:https://stackoverflow.com/questions/36554499/haskell-have-a-function-return-an-empty-character

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!