-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Andrew Foggin wrote:
> Tony Morris wrote:
>> This would require me to 'newtype' each time I want to instance Monad
>> (or whatever) right? Suppose I have some type T whose source I cannot
>> modify, I would not be able to declare T an instance of any of the
>> above, correct? I find this to be a limitation (the same I have been
>> accepting for quite some time now), especially given the
>> non-transitivity limitation of implicit defs.
>>
>
> I'm not sure I understand the problem. Do you have a simple example of
> what you would like to do? (in Scala if possible, as I'm not familiar
> with Haskell)
How are you proposing we get an instance of Monad for Option? Does this
require you to "PIMP" the existing Option? If not, then great! But I
can't see how. I'm really just trying to minimise the burden on the
client in both syntax and "instancing".
>
>> Ultimately, I have it down to "the explicit need to apply the
>> higher-ranked type argument with a newtype/PIMP", which is not very
>> nice, but annoyingly redundant nonetheless. Perhaps I should write all
>> this up as per Matt's request.
>>
>
> Yes please!
/me purchases a block of spare time ;)
>
>> I have also done away with subclassing, since I prefer the more
>> 'type-class' approach, despite once again, the lack of transitivity of
>> implicits. For example, Monad is an abstract class that accepts an
>> implicit Functor argument.
>>
>
> This feels to me a little like cutting across the grain of the language...
I agree and I haven't concluded that this solution is best yet.
>
>> Regarding, MonadWithZero, you might consider splitting into two
>> different traits that follow different laws. I am an advocate of fixing
>> one of Haskell's mistakes (and not repeating it in Scala):
>>
>>
http://www.haskell.org/haskellwiki/MonadPlus_reform_proposal>>
>>
>>
> Very good point! Here's the result:
>
> trait Monads {
> type M[+A]
>
> def unit[A](a : => A) : M[A]
> def zero : M[Nothing] = error("zero not defined")
>
> trait Functor[+A] { self : M[A] =>
> def map[B](f : A => B) : M[B]
> }
>
> trait Monad[+A] extends Functor[A] { self : M[A] =>
> def flatMap[B](f : A => M[B]) : M[B]
> def map[B](f : A => B) = flatMap { a => unit(f(a)) }
> def filter[B >: A](f : A => Boolean) = flatMap { a => if (f(a))
> unit(a) else zero }
> }
>
> trait Plus[+A] { self : M[A] =>
> def plus[B >: A](other : => M[B]) : M[B]
> }
>
> trait OrElse[+A] { self : M[A] =>
> def orElse[B >: A](other : => M[B]) : M[B]
> }
>
> trait Zero extends Monad[Nothing] { self : M[Nothing] =>
> def flatMap[B](f : Nothing => M[B]) : M[B] = this
> }
>
> trait ZeroPlus extends Zero with Plus[Nothing] { self : M[Nothing] =>
> def plus[B](other : => M[B]) = other
> }
>
> trait ZeroOrElse extends Zero with OrElse[Nothing] { self : M[Nothing] =>
> def orElse[B](other : => M[B]) = other
> }
> }
Looking good ;)
Why is zero on monad and not Zero?
I was thinking of a hierarchy as follows:
Functor
Monad extends Functor
MonadZero extends Monad
MonadPlus extends MonadZero
MonadOrElse extends MonadZero
>
> -- Andrew
>
>
>
- --
Tony Morris
http://tmorris.net/Hey! We had 40,000 lines of C# here yesterday, but now there are 40
lines of... Dear God, what is a catamorphism?"
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla -
http://enigmail.mozdev.orgiD8DBQFHlPvzmnpgrYe6r60RAs9VAJwL1xmp3jyoUIVOjA0+mudJl4htxgCbBARQ
ZNfnXYp631+xQiuLK0jzSns=
=KVoX
-----END PGP SIGNATURE-----