- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Re: i think i got it (monads and stuff)
Tue, 2011-07-26, 07:00
if i add implicits, monads containing only the information how to do
something make sense. i've seen a certain video about scalaz (Nick
Partridge was talking i think) and monoids, and understood that one
:)
Am 26.07.2011 00:50, schrieb Razvan Cojocaru:
Am 26.07.2011 00:50, schrieb Razvan Cojocaru:
So to fully answer the puzzle below, the Monad used by Tony is separate from the actual container F, so that you can use it on types you get from some library. I believe that scalaz uses that together with implicit conversions to make these look nice on the underlying containers. There be dragons - very advanced stuff there, well over my head and/or effort allotted J but I think I get the 10kfeet picture.
So, if you get a container C[_] from somewhere, you write the CM[C] monadic implementation for it and an implicit conversion and then some magic happens…
Check this out for a moment:
https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/Bind.scala
and this
https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/Scalaz.scala
cheers,
Razie
From: scala-user@googlegroups.com [mailto:scala-user [at] googlegroups [dot] com] On Behalf Of HamsterofDeath
Sent: July-25-11 5:39 PM
To: scala-user@googlegroups.com
Subject: Re: [scala-user] i think i got it (monads and stuff)
the longer i look at this
trait Monad[M[_]] {
def bind[A, B](ma:M[A])(f:A => M[B]):M[B]
def unit[A](a:A):M[A]
def fmap[A, B](f:A => B):M[A] => M[B]
def ap[A, B](f:M[A => B]):M[A] => M[B]
}
the less sense it makes.
i understand wrapping a:A in m:M[A].
i understand mapping M[A] to M[B]
simple.
i understand if you say "monad = both methods together", making a monad a utiliy object, not different from the well known *Utils-classes of java.
i understand how option works.
but i cannot make the mental jump to the monad trait. the implementation is nothing more than a function composer which i simply could do directly or via not-part-of-a-trait utility-methods if the logic is more complex.
my brain refuses to see any sense in an implementation of a monad trait that does not return an instance of monad in the bind and unit method and accepts an instance of monad in the bind method.
Am 25.07.2011 22:37, schrieb Sébastien Bocq:I mean this is implementation specific.
2011/7/25 Sébastien Bocq <sebastien [dot] bocq [at] gmail [dot] com" rel="nofollow">sebastien.bocq@gmail.com>
I'd like to know other opinions, but I find that avoiding OO makes it easier to reason about these abstract concepts in Scala. Here is my version of the identity monad:
trait Monad[M[_]] {
def bind[A, B](ma:M[A])(f:A => M[B]):M[B]
def unit[A](a:A):M[A]
def fmap[A, B](f:A => B):M[A] => M[B]
def ap[A, B](f:M[A => B]):M[A] => M[B]
}
type Id[A] = A
implicit val mId = new Monad[Id] {
def bind[A, B](a:Id[A])(f:A => Id[B]) = f(a)
def unit[A](a:A) = a
def fmap[A, B](f:A => B) = f
def ap[A, B](f:Id[A => B]) = f
}
(See how identity fmap a function to itself.)
Now you can box the monad inside an object to use it in a for-comprehension but this is incidental (I'm wondering if the boxing is optimized away by the JVM).
trait MonadTrait[M[_], A] {
def flatMap[B](f:A => M[B]):M[B]
def map[B](f:A => B):M[B]
}
implicit def idBox[A](ma:Id[A])(implicit m:Monad[Id]) = new MonadTrait[Id, A] {
def flatMap[B](f:A => Id[B]) = m.bind(ma)(f)
def map[B](f:A => B):Id[B] = m.fmap(f)(ma)
}
def test(x:Id[Int]) = for {
y <- x * x
z <- y + y
} yield (y + z)
println(test(42))
Have fun!
2011/7/25 HamsterofDeath <h-star [at] gmx [dot] de" target="_blank" rel="nofollow">h-star@gmx.de>
this compiles:
trait Monad[F[_]] {
def point[A](a: => A): F[A]
def bind[A, B](f: A => F[B]): F[A] => F[B]
}
case class Identity[A](a: A)
object Monad {
val IdentityMonad: Monad[Identity] = new Monad[Identity] {
def bind[A, B](f: (A) => Identity[B]) = (e:Identity[A]) => f(e.a)
def point[A](a: => A) = Identity(a)
}
}
val identity = Monad.IdentityMonad.point("hi")
val transformer = Monad.IdentityMonad.bind((e: String) => Monad.IdentityMonad.point(e.toInt))
val wohoo = transformer.apply(identity)
Am 24.07.2011 23:10, schrieb Tony Morris:
> trait Monad[F[_]] {
> def point[A](a: => A): F[A]
> def bind[A, B](f: A => F[B]): F[A] => F[B]
> }
>
> case class Identity[A](a: A)
>
> object Monad {
> val IdentityMonad: Monad[Identity] = error("todo")
> }
--
Sébastien
--
Sébastien