依赖方法类型,以前是一个实验性的特性,现在已经变成了enabled by default in the trunk,显然这似乎在Scala社区中创建了some excitement。
乍一看,这有什么用还不是一目了然。Heiko Seeberger发布了一个依赖方法类型here的简单示例,可以在注释中看到,它可以很容易地在方法上使用类型参数重现。所以这不是一个很有说服力的例子。(我可能遗漏了一些明显的东西。如果是这样,请纠正我。)
在依赖方法类型明显优于其他方法的情况下,有哪些实用和有用的用例示例?
我们可以用它们做些以前不可能/容易做的有趣的事情吗?
与现有的类型系统特性相比,它们给我们带来了什么?
此外,依赖方法类型是否与其他高级类型语言(如Haskell、OCaml )的类型系统中的任何功能相似或从中汲取灵感?
发布于 2011-10-23 00:14:05
trait Graph {
type Node
type Edge
def end1(e: Edge): Node
def end2(e: Edge): Node
def nodes: Set[Node]
def edges: Set[Edge]
}
在其他地方,我们可以静态地保证我们不会混淆来自两个不同图的节点,例如:
def shortestPath(g: Graph)(n1: g.Node, n2: g.Node) = ...
当然,如果在Graph
中定义的话,这已经可以工作了,但是假设我们不能修改Graph
,并且正在为它编写一个"pimp my library“扩展。
关于第二个问题:此功能支持的类型比完全依赖的类型弱得多(有关这方面的信息,请参阅Dependently Typed Programming in Agda )。我想我以前没见过这样的类比。
发布于 2012-04-24 20:08:14
当具体的abstract type members are used instead of type parameters时需要这个新功能。当使用类型参数时,family polymorphism类型依赖关系可以在最新版本和一些较旧版本的Scala中表达,如下面的简化示例所示。
trait C[A]
def f[M](a: C[M], b: M) = b
class C1 extends C[Int]
class C2 extends C[String]
f(new C1, 0)
res0: Int = 0
f(new C2, "")
res1: java.lang.String =
f(new C1, "")
error: type mismatch;
found : C1
required: C[Any]
f(new C1, "")
^
发布于 2012-02-06 02:24:04
我的developing a model支持使用环境状态的声明性编程形式。细节在这里是不相关的(例如,关于回调的细节以及与Actor模型结合序列化程序的概念相似性)。
相关的问题是状态值存储在散列映射中,并由散列键值引用。函数输入不变的参数,这些参数是来自环境的值,可以调用其他这样的函数,并将状态写入环境。但函数不允许从环境中读取值(因此函数的内部代码不依赖于状态更改的顺序,因此在这种意义上仍然是声明性的)。如何在Scala中输入?
环境类必须有一个重载方法,该方法输入这样一个要调用的函数,并输入该函数的参数的散列键。因此,此方法可以从散列映射调用具有所需值的函数,而无需提供对这些值的公共读取访问(因此,根据需要,拒绝函数从环境中读取值的能力)。
但是,如果这些散列键是字符串或整数散列值,则散列映射元素类型subsumes的静态类型为Any或AnyRef (下面未示出的散列映射代码),因此可能发生运行时不匹配,即,可以将任何类型的值放入给定散列键的散列映射中。
trait Env {
...
def callit[A](func: Env => Any => A, arg1key: String): A
def callit[A](func: Env => Any => Any => A, arg1key: String, arg2key: String): A
}
尽管我没有测试以下内容,但从理论上讲,我可以在运行时使用classOf
从类名中获取散列键,因此散列键是一个类名而不是字符串(使用Scala的反号在类名中嵌入字符串)。
trait DependentHashKey {
type ValueType
}
trait `the hash key string` extends DependentHashKey {
type ValueType <: SomeType
}
这样就实现了静态类型安全。
def callit[A](arg1key: DependentHashKey)(func: Env => arg1key.ValueType => A): A
https://stackoverflow.com/questions/7860163
复制相似问题