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




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

Reply via email to