[Haskell-cafe] defining mapPairs function
Dan Weston
westondan at imageworks.com
Thu Aug 30 15:36:53 EDT 2007
That's just a minor change of plumbing:
import Control.Arrow((***),(&&&),(>>>),app)
import Data.Maybe(catMaybes,maybeToList)
mapPair :: (a -> a -> a) -> [a] -> [a]
mapPair = curry mp where
mp = (((zipWith >>> uncurry) *** -- (inter-elem function
(id &&& tail) >>> -- ,duplicate and offset)
app >>> -- apply fst to snd
alternate >>> -- mark even elements
catMaybes)) -- delete even elements
&&& -- Tuple this up with...
(snd >>>
alternate >>> -- keep odd indices
(Nothing:) >>> -- make sure there is a last
last >>> -- get last
maybeToList) -- keep if it had odd index
>>> -- and then...
uncurry (++) -- append pair of lists
alternate = zipWith ($) (cycle [Just,const Nothing])
-- Mark even-indexed elements for deletion
-- cycle goes on forever, but zipWith stops at
-- the end of the shorter list, so no worries.
When you find yourself manually plumbing the inputs, that's probably
where point-free has morphed into point-less programming! I plead guilty! :)
Dan Weston
Devin Mullins wrote:
> That's great (really, thank you for such a fun example of Arrow
> programming), but isn't the (*) on line two of mapPair supposed to be a
> "point"? How would you make a point-less version of mapPair that
> actually had the type signature (a->a->a)->[a]->[a]*? (For that matter,
> /would/ you?)
>
> Devin
> * Grr, you're right. Were it not for that odd requirement, the type
> could be loosened to (a->a->b)->[a]->[b]. Maybe mapPairs should take a
> monadic (that is, one-arg) function to handle the dangling oddies.
>
> Dan Weston wrote:
>> import Control.Arrow((&&&),(>>>))
>> import Data.Maybe(catMaybes,maybeToList)
>>
>> mapPair = (id &&& tail >>> -- offset list by one
>> uncurry (zipWith (*)) >>> -- multiply adjacent
>> alternate >>> -- mark even elements
>> catMaybes) -- delete even elements
>>
>> &&& -- Tuple this up with...
>>
>> (alternate >>> -- keep odd indices
>> (Nothing:) >>> -- make sure there is a last
>> last >>> -- get last
>> maybeToList) -- keep if it had odd index
>>
>> >>> -- and then...
>>
>> uncurry (++) -- append pair of lists
>>
>> where alternate = zipWith ($) (cycle [Just,const Nothing])
>> -- Mark even-indexed elements for deletion
>> -- cycle goes on forever, but zipWith stops at
>> -- the end of the shorter list, so no worries.
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
More information about the Haskell-Cafe
mailing list