Picon

Applicative functors with branch/choice ?

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
(Continue reading)

Strake | 26 Jul 00:14 2012
Picon

Re: Applicative functors with branch/choice ?

On 25/07/2012, Евгений Пермяков <permeakra <at> gmail.com> wrote:
> Let assume, that some computation takes argument and produces value
> Either a b. This computation may be represented in for different forms
>
> ====
> ...
> computeApplicative :: app a -> app (Either b c)
> ...
> =====

This seems rather more appropriate for Applicative:

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

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Twan van Laarhoven | 26 Jul 00:34 2012
Picon

Re: Applicative functors with branch/choice ?

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

(Continue reading)

Dominique Devriese | 26 Jul 07:28 2012
Picon

Re: Applicative functors with branch/choice ?

Евгений,

> 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

What about the following alternative that does not require an extension?

  import Control.Applicative

  eitherA :: Applicative f => f (a -> c) -> f (b -> c) -> f (Either a b) -> f c
  eitherA = liftA3 either

Note by the way that the result of this function will execute the
effects of all of its arguments (as you would expect for an
Applicative functor).

Dominique

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Ross Paterson | 26 Jul 10:48 2012
Picon

Re: Applicative functors with branch/choice ?

On Wed, Jul 25, 2012 at 09:22:23PM +0100, Евгений Пермяков wrote:
> 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

Do you have any instances in mind?

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Picon

Re: Applicative functors with branch/choice ?

well...  This code is both demonstration for use case and more sane 
class + instance
typeclass name is selected quite randomly, may be native speaker will 
select a better one

module Actuative where
import Control.Applicative
import System.IO
import System.IO.Error

-- | minimal complete definition : select
class Applicative f => Actuative f where
  -- | select computation conditionally . Side effects of only one two 
alternative take place
  select      :: f (Either a b)  -- ^ selector
                  -> f (a -> c) -- ^ first alternative
                  -> f (b -> c) -- ^ second alternative
                  -> f c
  -- | correct possible error
  correct     :: f (Either a b) -> f (a -> b) -> f b
  correct i l  = select i l (pure (\x -> x))
  -- | similiar for select, but mimics ArrowChoice
  branch      :: f (Either a b) -> f (a -> c) -> f (b -> d) -> f (Either 
c d)
  branch i l r = select i (pure (\f x -> Left (f x)) <*> l) (pure (\f x 
-> Right (f x)) <*> r)
  -- | execute only if Left
  onLeft      :: f (Either a b) -> f (a -> c) -> f (Either c b)
  onLeft i l   = branch i l (pure (\x -> x))
  -- | execute only if Right
(Continue reading)

Twan van Laarhoven | 26 Jul 13:14 2012
Picon

Re: Applicative functors with branch/choice ?

On 26/07/12 12:40, Евгений Пермяков wrote:
> class Applicative f => Actuative f where
>   -- | select computation conditionally . Side effects of only one two
> alternative take place
>   select      :: f (Either a b)  -- ^ selector
>                   -> f (a -> c) -- ^ first alternative
>                   -> f (b -> c) -- ^ second alternative
>                   -> f c

Can't you already define this function in terms of Applicative itself? I.e.

     select xs fs gs = sel <$> xs <*> fs <*> gs
       where
         sel (Left  a) f _ = f a
         sel (Right b) _ g = g b

I assume that your intent is that `select` behaves differently from the one I 
defined here. But you need to specify in what way.

Suppose it should work like if-then-else. Then you would perhaps have these laws:

     select (Left <$> x) f g = f <$> x
     select (fmap swapEither x) f g = select x g f

I think this is a useful class to have, and I would support adding something 
like it to the standard library. Perhaps the arguments should be swapped to the 
same order as either, to give

     class Functor f => Selective f where
         eitherF :: f (a -> c) -> f (b -> c) -> f (Either a b) -> f c
(Continue reading)

Picon

Re: Applicative functors with branch/choice ?

May be difference will be more clear with this example ?

import Control.Monad.State

instance (Functor m, Monad m) => Actuative (StateT s m) where
  select i l r = do
    iv <- i
    case iv of
     Left lv  ->  l >>= \lf -> return (lf lv)
     Right rv ->  r >>= \rf -> return (rf rv)

select' xs fs gs = sel <$> xs <*> fs <*> gs
       where sel (Left  a) f _ = f a
             sel (Right b) _ g = g b

increment :: Monad m => StateT Int m (() -> ())
increment = get >>= (put . (+1)) >> return (const ())

====
the difference may be seen clearly, when you run in ghci

*Actuative> runState (select' (return $ Left ()) increment (increment *> 
increment *> increment)) 0
((),4)
*Actuative> runState (select (return $ Left ()) increment (increment *> 
increment *> increment)) 0
((),1)

Not sure, what categorical concept is model for this type class

(Continue reading)

Twan van Laarhoven | 26 Jul 14:12 2012
Picon

Re: Applicative functors with branch/choice ?

On 26/07/12 13:58, Евгений Пермяков wrote:
> As you can see, if I use select definition with Control.Applicative.<*>, I'll
> execute both l and r and the only choice will be, what result to drop. Both l
> and r, however, will be executed, and their side effects will take place. With
> select from my code only one action will be executed, depending on result of i,
> and only effects of one of actions (either l or r) will take place.

I realize that, and that is why I insisted on laws to formalize this.

Your instance for IO is a special case of a function that works for any Monad:

     defaultEitherF :: (Functor f, Monad f)
                    => f (a -> c) -> f (b -> c) -> f (Either a b) -> f c
     defaultEitherF ml mr mx = either (ml <$$>) (mr <$$>) =<< mx
       where
         (<$$>) :: Functor f => f (a -> b) -> a -> f b
         f <$$> x = ($ x) <$> f

(the version of this function in my previous post was not correct)

>
> I'm not sure, what categorical concept will correspond to this typeclass.
>

Well, this type class kind of corresponds to the functionality of ArrowChoice. I 
believe that class corresponds to a (symmetric) monoidal structure on the dual 
category. Plus a whole bunch of junk you get from its super classes.

Twan

(Continue reading)


Gmane