On 2012-07-25 22:22, Евгений Пермяков wrote:
Let assume, that some computation takes argument and produces value Either a b.
This computation may be represented in for different forms

====
computePure :: a -> Either b c

computeMonad :: a -> m (Either b c)

computeApplicative :: app a -> app (Either b c)

computeArrow :: arr a (Either b c)
=====
And now, having result, we need to execute several actions, making a choice,
what actions to perform for Left and Right tags of Either. Pure function and
monads are easy, as there is way to pattern-match on value and take actions
depending on result. There is an extension to Arrow class that do the job --
ArrowChoice. However, I cannot find any way to make choice for Applicative. It
seems that both Applicative and Alternative are not suited for it.

So, it seems for me, that Applicative API should be extended with typeclass for
making choice what actions to execute depending on result of some test (pattern
matching). Is there any reasonable definition of such typeclass or clear
explanation, why such typeclass is unneeded?

The possible extension may look somehow like this:

class Applicative a => Branching a where
  branch :: a (Either b c) -> (a b -> a d) -> (a c -> a d) -> a d

A nicer typeclass is perhaps the dual to applicative. Given a functor, (<*>) is equivalent to the function pair:

    class Functor f => Pairing f where
        pair :: (f a, f b) -> f (a,b)
        -- pair (x,y) = (,) <$> x <*> y
        -- (<*>) x y = ($) <$> pair (x,y)

You can form the dual of pair by flipping the arrows and replacing products by sums, which gives:

    class Functor f => Branching f where
        liftEither :: f (Either a b) -> Either (f a, f b)

Which looks almost equivalent to your Branching class. But I can't think of any non-trivial functors that are an instance of this class. Perhaps a better typeclass is the one where you keep the product on the result side:

    class Functor => Partitionable f where
        partitionEithers :: f (Either a b) -> (f a, f b)

You can build some useful functions on top of partionEithers, such as `partition` and `filter`.

    filter = fst . partition
    partition pred = partitionEithers . fmap side
        where side x = if pred x then Left x else Right x

I don't know if it is enough for your ArrowChoice instance.


Twan

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to