-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Sebastian Hanowski wrote:
>> instance MonadPlus D where
>>  mzero = never
>>  mplus (Now a) _ = Now a
>>  mplus _ (Now a) = Now a
>>  mplus (Later d1) (Later d2) = mplus d1 d2
> 
> Note that you have to record the depth of the recursion
> 
>         mplus (Later d1) (Later d2) = Later (mplus d1 d2)
> 
> or else you won't have
> 
>         mplus never never =~ never
> 
> and hence loose associativity.

(mplus never never) _should_ be (never), right?

A different sort of implementation could run the two computations in
parallel, threads-style, and return whichever one finished first.
(subject to having a slightly different semantics - see my next comment)

> 
>> Although, this can pick an arbitrary answer based on the number of
>> cycles of recursion for each. What I was initially thinking was just for
>> functions like (&&).  In Haskell they're asymmetric, strict in the first
>> argument, where if it's False the whole function is false.  What would
>> be nice is a combinator that says that if partial argument A is foo, OR
>> partial argument B is bar, the whole function's answer is quux, no
>> matter if the other partial argument was _|_.
> 
> Doesn't your mplus just do that?
> 
>         mplus x never --> x
>         mplus never y --> y

It does fulfill the laws of MonadPlus, as you note - the only thing I
don't like is mplus being either asymmetric(mplus x y /= mplus y x, if
neither x nor y is never) or non-pure(nondeterministic).
((return 1) `mplus` (return 2)) would have to choose somehow which
argument to return, whereas I'm looking for something where there is
only a single answer that can be correctly returned by examining just
one of the two arguments. (unless there are some weird functions where
examining either argument can not only tell you what the answer is, but
depending on what that argument was, the result might have more than one
possibility.)

> 
>> e.g.
>> (&&): False or False --> False
>> (||): True or True --> True
>> (\a b -> a && not b):
>>       False or True --> False
> 
> What's unpleseant  here is that  these boolean functions seem  to loose
> their beloved short circuiting behaviour
> 
>        False && undefined --> False 
>        True || undefined  --> True      
> 
> but
> 
>         liftM2 (&&) (Now False) never ~= never
>         liftM2 (||) (Now True) never ~= never

As you show, they keep their short circuiting behavior - as well as
gaining symmetric short-circuiting behavior such that (flip (&&)) =
(&&), for example...?  How do they "seem to" lose their short circuiting
behavior?-- I think at least one of us isn't understanding the other one
yet.

> 
> Seems that the delay monad is not an applicative functor.

Aren't ALL monads applicative functors? (though not the converse), with:
pure = return
(<*>) = ap

And here are some invented (untested) direct definitions:
instance Functor D where
    fmap f (Now a) = Now (f a)
    fmap f (Later d) = Later (fmap f d)
instance Applicative D where
    pure = Now
    Now f <*> ma = fmap f ma
    Later df <*> ma = Later (df <*> ma)



Cheers,
Isaac


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGErNDHgcxvIWYTTURAjzPAJ9HSPrfvOKHBfi6rVnpmg/CJqlzZwCfTSx8
AVc41JB2hwLp8kEwl+CTYBw=
=5QW5
-----END PGP SIGNATURE-----

Reply via email to