我试图通过实现一个描述 monad 的非常基本的接口(interface)来掌握 scala 中的高阶多态性,但我遇到了一个我不太了解的问题。
我用 C++ 实现了相同的代码,代码如下所示:
#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;
}
当尝试对 scala 做同样的事情时,我失败了:
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)
}
}
编译器提示:
[raichoo@lain:Scala]:434> scalac highorder.scala
highorder.scala:5: error: not found: value Container
Container[A](a)
^
one error found
我在这里做错了什么?似乎有一个关于 scala 类型构造函数的基本概念我似乎不了解。
问候,
来秋
最佳答案
Monad
Scala 中的 trait 声明如下:
trait Monad[M[_]] {
def pure[A](a: => A): M[A]
def bind[A,B](a: M[A], f: A => M[B]): M[B]
}
请注意,它是使用类型构造函数参数化的
M[_]
.括号内的下划线表示 M
是一种类型构造函数 (* -> *)
(即 M
采用某种类型 A
来构造类型 M[A]
)。然后,您的身份单子(monad)实例将像这样编写: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)
}
此定义使用按名称参数来实现惰性语义。
Scalaz 提供了 Monad 和其他有用的高级类型类。库以及许多标准 Java/Scala 库的实例。
关于scala - scala中高阶多态性的常见做法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2578281/