Common practice for higher order polymorphism in scala

I am trying to understand a higher order polymophism in scala by implementing a very simple interface that describes a monad, but I am facing a problem that I really don't 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 crash:

 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:

 [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 that I don't seem to understand about scala constructors.

Regards, raichoo

+7
polymorphism types scala monads
source share
3 answers

The Monad score in Scala will be announced 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 is parameterized by a constructor of type M[_] . The underlined underlines indicate that M is a constructor of type (* -> *) (that is, M takes some type A to construct type M[A] ). Then the instance of your monad will be written as follows:

 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 name-name parameters to achieve lazy semantics.

Monads and other useful higher classes are provided by the Scalaz library, as well as many instances for standard Java / Scala.

+16
source share

If you change the definition of the Monad class to the following

 class Monad[Container[_]] { def pure[A <% Container[A]](a: A): Container[A] = a } 

The syntax of Container[_] is how higher types are expressed in Scala. A <% Container[A] is the "presentation border" that expresses that A implicitly converted to Container[A] . The body of the method uses this implicit conversion. To use this class, you need to have an implicit conversion to the scope (in your example) Int to Value[Int]

 implicit def toValue[T](t:T) = new Value(t) 

Then you can do the following

 scala> val m = new Monad[Value] m: Monad[Value] = Monad@781fb069 scala> m.pure(1).value res3: Int = 1 
+5
source share

Not sure what would be the best solution, but in a pure definition in your code:

 class Monad[Container[T]] { def pure[A](a: A): Container[A] = Container[A](a) } 

What to do Container[A](a) ? So far you have defined Container as a generic type XXX, and you have no information on how to create a new object. You need to pass the builder object as an implicit parameter. See how library libraries are implemented in Scala 2.8 or the Monad definition in Scalaz

+3
source share

All Articles