Reputation: 1143
I saw the below code on SO. But the problem it has is that it's map
and flatMap
definitions aren't fully correct. map
must be able to transform the inside value of a monadic container/context, and the same way a flatMap
should take a value, transform it and put it back in the monadic context/container. In the example below it's taking an A
and giving an A
or M[A]
(instead of A->B
or A->M[B]
)
trait Mine[A] {
def get(): A
def map(f: A => A): Mine[A]
def flatMap(f: A => Mine[A]): Mine[A]
}
case class Attempt1[A, B](a: (A, B)) extends Mine[(A, B)] {
def get(): (A, B) = a
def map(f: ((A, B)) => (A, B)): Mine[(A, B)] = {
Attempt1(f(a._1, a._2))
}
def flatMap(f: ((A, B)) => Mine[(A, B)]): Mine[(A, B)] = {
f(a._1, a._2)
}
}
So I thought of changing it and that's where I got stuck. The below code is failing for all the right reasons but can someone guide on how to implement something similar?
trait Opt[A] {
def map[B](f: A => B): Opt[B]
def flatMap[B](f: A => Opt[B]): Opt[B]
}
case class Osome[A, B](a: (A, B)) extends Opt[(A, B)] {
def flatMap[C, D](f: ((A, B)) => Opt[(C,D)]): Opt[(C, D)] = {
f(a._1, a._2)
}
def map [C, D] (f: ((A, B)) => (C, D)): Opt[(C, D)] = {
Osome(f(a._1, a._2))
}
}
Upvotes: 0
Views: 123
Reputation: 24403
The problem is, that you don't implement the map
and flatMap
methods of Opt
in your Osome
class, but you overload them. In your trait they both have one type parameter, but in your implementation they have two. Aside from that, your Osome
would anyway not be a monad, as it restricts the resulting type of map
and flatMap
, where monads allow for arbitrary types.
Upvotes: 1