maybe use for functors or arrows?

Is there a way to write the function process :: [(Location,Item)] -> [(Location,ValuableItem)] given a function indicating which Item's to keep transform :: Item -> Maybe ValuableItem using functors and arrows? The value for location stays with any item that is kept. What I have is process inp = catMaybes (map g inp) where g (l,i) = case transform i of Nothing -> Nothing Just v -> Just (l,v) This looks like an arrow situation to me because you want to make a function that acts on the second value in a tuple, and a little bit like a Maybe functor. Thanks, Mike

Hi Michael The /case transform i of .../ code should be able to be rephrased with fmap as it is "putting back" the first element of the tuple if /transform/ produces a (Just) value. fmap (\a -> (a,v)) Personally, I would look to avoiding building the list of type ::Maybe (Location,ValuableItem) during the first traversal (via map) to later filter them out with a second traversal via catMaybes. The optimization technique "stream fusion" can often collapse compositions of list functionals (map, filter, etc). into one traversal. But it isn't available by default - you have to install the stream-fusion library. Also a composition of functionals isn't necessarily clearer than a direct implementation. Best wishes Stephen

Michael Mossey wrote:
Is there a way to write the function
process :: [(Location,Item)] -> [(Location,ValuableItem)]
given a function indicating which Item's to keep
transform :: Item -> Maybe ValuableItem
using functors and arrows? The value for location stays with any item that is kept.
What I have is
process inp = catMaybes (map g inp) where g (l,i) = case transform i of Nothing -> Nothing Just v -> Just (l,v)
This looks like an arrow situation to me because you want to make a function that acts on the second value in a tuple, and a little bit like a Maybe functor.
import Control.Arrow ((***)) process = catMaybes . map (uncurry (liftM2 (,)) . (return *** transform)) Whether this is more readable is another question. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

On Sun, Jun 27, 2010 at 09:59:42AM +0200, Heinrich Apfelmus wrote:
Michael Mossey wrote:
Is there a way to write the function
process :: [(Location,Item)] -> [(Location,ValuableItem)]
given a function indicating which Item's to keep
transform :: Item -> Maybe ValuableItem
using functors and arrows? The value for location stays with any item that is kept.
What I have is
process inp = catMaybes (map g inp) where g (l,i) = case transform i of Nothing -> Nothing Just v -> Just (l,v)
This looks like an arrow situation to me because you want to make a function that acts on the second value in a tuple, and a little bit like a Maybe functor.
import Control.Arrow ((***))
process = catMaybes . map (uncurry (liftM2 (,)) . (return *** transform))
One could also do process = catMaybes . map (sequenceA . second transform) where Data.Traversable.sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a) is used to "lift" the Maybe from the inside of the tuple to apply to the whole tuple, specifically sequenceA :: (a, Maybe b) -> Maybe (a,b) Unfortunately this will not work without a Traversable instance for ((,) a), which doesn't already exist, but it ought to, and it's easy to make: import Data.Foldable import Data.Traversable instance Foldable ((,) a) where foldMap = foldMapDefault instance Traversable ((,) a) where sequenceA (a,fb) = fmap ((,) a) fb -Brent
Whether this is more readable is another question.
Regards, Heinrich Apfelmus
-- http://apfelmus.nfshost.com
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (4)
-
Brent Yorgey
-
Heinrich Apfelmus
-
Michael Mossey
-
Stephen Tetley