I'm trying to grasp higher-order-polymophism in scala by implementing a very basic interface that describes a monad but I come across a problem that I don't really understand.
I implemented the same with C++ and the code looks like this:
#include <iostream>
template <typename T>
class Value {
private:
T value;
public:
Value(const T& t) {
this->value = t;
}
T get() {
return this->value;
}
};
template < template <typename> class Container >
class Monad {
public:
template <typename A> Container<A> pure(const A& a);
};
template <template <typename> class Container>
template <typename A>
Container<A> Monad<Container>::pure(const A& a) {
return Container<A>(a);
}
int main() {
Monad<Value> m;
std::cout << m.pure(1).get() << std::endl;
return 0;
}
When trying to do the same with scala I fail:
class Value[T](val value: T)
class Monad[Container[T]] {
def pure[A](a: A): Container[A] =
Container[A](a)
}
object Main {
def main(args: Array[String]): Unit = {
val m = new Monad[Value]
m.pure(1)
}
}
The compiler complains about:
[raichoo@lain:Scala]:434> scalac highorder.scala
highorder.scala:5: error: not found: value Container
Container[A](a)
^
one error found
What am I doing wrong here? There seems to be a fundamental concept I don't seem to understand about scala typeconstructors.
Regards, raichoo
The Monad
trait in Scala would be declared as follows:
trait Monad[M[_]] {
def pure[A](a: => A): M[A]
def bind[A,B](a: M[A], f: A => M[B]): M[B]
}
Note that it's parameterized with a type constructor M[_]
. The bracketed underscore indicates that M
is a type constructor of kind (* -> *)
(i.e. M
takes some type A
to construct a type M[A]
). Your identity monad instance would then be written like this:
class Value[A](a: => A) { lazy val value = a }
implicit val identityMonad = new Monad[Value] {
def pure[A](a: => A) = new Value(a)
def bind[A,B](a: Value[A], f: A => Value[B]) = new Value(f(a.value).value)
}
This definition uses by-name parameters to achieve lazy semantics.
Monad and other useful higher-kinded type classes are provided by the Scalaz library along with a lot of instances for the standard Java/Scala libraries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With