patternMinor
Writing Data.List's intersperse
Viewed 0 times
listinterspersewritingdata
Problem
Learn You a Haskell shows the
Note that the interspersed element only appears inside of the elements.
list elem ... item ... list elem ..... item .. list elem
Originally, I tried to write this function in terms of a
But, my approach failed since interspersed item was getting appended to the last element. Also, the lambda appended (
So I decided to use
Could the
intersperse function:ghci> intersperse '.' "MONKEY"
"M.O.N.K.E.Y"
ghci> intersperse 0 [1,2,3,4,5,6]
[1,0,2,0,3,0,4,0,5,0,6]Note that the interspersed element only appears inside of the elements.
list elem ... item ... list elem ..... item .. list elem
Originally, I tried to write this function in terms of a
fold.intersperse' :: [a] -> a -> [a]
intersperse' ys i = foldl (\acc x -> acc ++ [x] ++ [i]) [] ysBut, my approach failed since interspersed item was getting appended to the last element. Also, the lambda appended (
++) to the acc each time, which isn't good.So I decided to use
pattern matching:is' :: [a] -> a -> [a]
is' [] _ = []
is' (x:xs) i
| null xs = [x]
| otherwise = x : (i : (is' xs i))Could the
fold approach have worked? If so, how? Also, how's my is' implementation?Solution
Could the fold approach have worked? If so, how?
In the fold, we cannot access the rest of the input, only the rest of the output. However, if and only if the input was empty, the output will be empty. So
Interesting aspects:
-
I changed the argument order to match the standard
-
I use
-
I make sure that
intersperse' i = foldr (\x ys -> x : if null ys then [] else i : ys) []In the fold, we cannot access the rest of the input, only the rest of the output. However, if and only if the input was empty, the output will be empty. So
null ys happens to works here.Interesting aspects:
-
I changed the argument order to match the standard
intersperse. This happens to work better with the foldr-based definition. More importantely, I feel that intersperse is more often partially applied with an element than with a list, so the element should go first.-
I use
foldr instead of foldl to increase laziness and avoid the accumulator construction. Note how I don't need acc ++ [x] because I only add elements to the front of lists.-
I make sure that
intersperse' produces the first (:) cell before the null check.Code Snippets
intersperse' i = foldr (\x ys -> x : if null ys then [] else i : ys) []Context
StackExchange Code Review Q#48333, answer score: 5
Revisions (0)
No revisions yet.