« Return to Thread: defining mapPairs function

Re: defining mapPairs function

by Dan Weston :: Rate this Message:

Reply to Author | View in Thread

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@...
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@...
http://www.haskell.org/mailman/listinfo/haskell-cafe

 « Return to Thread: defining mapPairs function