nie*_*aki 8 haskell functional-programming scala
在Haskell中,您可以构建参数化类型,如以下示例所示:
data Tree a = Leaf | Node a (Tree a) (Tree a)
Run Code Online (Sandbox Code Playgroud)
..然后,如果type参数也是同一类型类的实例,则将它们作为类型类的实例(此处使用Eq作为示例,它可以是任何内容):
instance (Eq m) => Eq (Tree m) where
Leaf == Leaf = True
Node a b c == Node x y z = (a == x) && (b == y) && (c == z)
_ == _ = False
Run Code Online (Sandbox Code Playgroud)
我想知道在Scala中可能有类似的事情.要开始,让我们创建参数化类型:
abstract class Tree[T]
case class Leaf[T]() extends Tree [T]
case class Node[T](value: T, left: Tree[T], right: Tree[T]) extends Tree [T]
Run Code Online (Sandbox Code Playgroud)
..并选择一个更简单的特性作为实现的类型类:
trait Serializable {
def toDifferentString(): String
}
Run Code Online (Sandbox Code Playgroud)
现在我想要做的是提供Serializable
特征的实现Tree
,如果T
类型是Serializable
.
我可以看到几种如何部分地完成它的方法,但没有一种方法可以让我得到类似Haskell的结果:
:<
在Tree
抽象类中添加一个类型约束,但随后它变得不那么通用了,我假设我可以修改Tree
类Tree[Serializable]
到Serializable
,但我也不知道它会工作,这将是多么强劲.处理这个问题的好方法是什么?
Dan*_*ral 12
Scala中的类型类模式如下所示:
trait Serializable[-T] {
def toDifferentString(v: T): String
}
class SerializableTree[T : Serializable] extends Serializable[Tree[T]] {
def toDifferentString(t: Tree[T]) = t match {
case Leaf() => ""
case Node(v, left, right) =>
val vStr = implicitly[Serializable[T]].toDifferentString(v)
val lStr = toDifferentString(left)
val rStr = toDifferentString(right)
s"Node($vStr, $lStr, $rStr)"
}
}
object SerializableTree {
implicit def st[T : Serializable]: Serializable[Tree[T]] = new SerializableTree[T]
}
Run Code Online (Sandbox Code Playgroud)
Scala中的类型类是作为模式实现的,其中类型类提供一个或多个方法,这些方法将它们提供这些方法的类作为其参数之一.
表示法T : Serializable
是上下文绑定,相当于类型的隐式参数Serializable[T]
.通过implicitly[Serializable[T]]
(该方法implicitly[A]
返回类型的隐式参数A
)检索此隐式参数.
该对象SerializableTree
包含生成树的序列化程序所必需的定义,因此必须导入才能使用它.通常,类型类的常见定义放在类型类本身的对象伴随上,这使得它在没有导入的情况下可用.
因为我由Serializable
逆变中,Serializable[Tree[T]]
其中可以使用Serializable[Node[T]]
或Serializable[Leaf[T]]
是必需的.
归档时间: |
|
查看次数: |
487 次 |
最近记录: |