Reputation: 105
I've created a function m
such that
m "abc" "def" == "bcd"
and I would like to create another function that uses m
to generate the output ["bcd","efg","hia"]
when given the input ["abc","def","ghi"]
The definition of m
is
m :: [a] -> [a] -> [a]
m str1 str2 = (drop 1 str1) ++ (take 1 str2)
Upvotes: 5
Views: 177
Reputation: 28384
import Data.List.HT (rotate)
m2 :: [[a]] -> [[a]]
m2 list = zipWith m list (rotate 1 list)
where m
is yours.
You can make it point free in a couple of ways.
Here's using the Applicative
style,
m2 :: [[a]] -> [[a]]
m2 = zipWith m <$> id <*> (rotate 1)
which can read as m2
is the function that passes its argument to id
and rotate 1
respectively, and then those results to zipWith m
.
Here's using the Monad
ic style,
import Control.Monad (ap)
m2 :: [[a]] -> [[a]]
m2 = zipWith m `ap` rotate 1
which is imho a bit less clear, in this case; you can read it as m2
passes its argument to both zipWith m
and rotate 1
and then feeds the result of the latter to the the result of the former.
Honestly, I like the other answer a bit more, as it avoids importing rotate
and gets the same effect with tail . cycle
.
Upvotes: 3
Reputation: 476557
You can make use of zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
here where you take the entire list as first parameter, and tail (cycle l)
as second parameter (with l
the list):
combine :: [a] -> [a]
combine l = zipWith m l (tail (cycle l))
zipWith
will enumerate concurrently on both lists and each time call m
with an element of the first and the second list. For example:
Prelude> combine ["abc","def","ghi"]
["bcd","efg","hia"]
Upvotes: 4
Reputation: 35502
You can append the first element to the end to simulate a wrap-around, then zip the list with its tail to get tuples of each element, then map
it:
f :: [[a]] -> [[a]]
f [] = []
f l@(x:xs) = map (\(a, b) -> m a b) $ zip wrapped (tail wrapped)
where wrapped = l ++ [x]
Alternatively, you can use uncurry
:
f :: [[a]] -> [[a]]
f [] = []
f l@(x:xs) = map (uncurry m) $ zip wrapped (tail wrapped)
where wrapped = l ++ [x]
Upvotes: 3