【发布时间】:2023-03-29 12:07:01
【问题描述】:
我想为几个不同的C -s 定义一对类型(A 中的B 和B)。例如,A=String 和 B=View 代表 C=View1(在隐式对象 DepInstanceView1 中定义)。然后我想在类型类定义中使用这些类型级别的依赖关系。
如何定义一个类型类实例(此处为 ServerSideFun[View1]),它具有具有依赖输入和返回类型(此处定义为 DepInstanceView1)的函数?
换句话说,我想有一个来自C -> (A,B) 的类型级函数(这里在DepInstanceView1 中定义了一个这样的类型级映射)并在类型类声明中使用这个类型级函数(这里@ 987654336@) 及其实例(此处为View1Conv)。
有人可以建议一种方法吗?
或者如何修改下面的代码来编码这样的类型级别,类型类中f(正如trait ServerSideFun[C]所暗示的那样)的类型依赖约束?
我这样做的尝试以编译器错误告终:
source_file.scala:47: error: type mismatch;
found : Int(42)
required: B
def f[A, B] (a:A)(implicit aux:Dep.Aux[View1,A,B]):B = 42
^
one error found
代码示例:
下面的代码可以在这里在线执行:http://rextester.com/GYWW78561
object Rextester extends App {
println("Hello, World!3")
}
trait Dep[C]{
type A
type B
}
trait View1
trait View2
object Dep{
type Aux[C0, A0, B0]= Dep[C0] {type A=A0; type B= B0}
implicit object DepInstanceView1 extends Dep[View1] {
type A=String
type B=Int
}
}
trait ServerSideFun[C]
{
def f[A,B] (a:A)(implicit aux:Dep.Aux[C,A,B]):B
}
object ServerSideFun {
implicit object View1Conv extends ServerSideFun[View1]{
def f[A, B] (a:A)(implicit aux:Dep.Aux[View1,A,B]):B = 42
}
}
编辑:
我更新了代码以澄清意图:http://rextester.com/YVBV30174
这是:
1) 定义几个View-s:
trait View1trait View2
2) 为每个View-s 定义一个单独的类型级映射View -> (A,B),例如:
-
View1-> (String,Int)inDepInstanceView1 -
View2-> (String,String)在DepInstanceView2
3) 可以有多个不同的类型类ServerSideFun 实现,例如:
-
object ServerSideFun中的一个 -
object ServerSideFunAlternativeImplementation中的另一个。
本质上:
-
类型类
ServerSideFun[C]的所有 实例应遵循object Dep中定义的类型级别映射View -> (A,B)。 - 因此,对于给定的
View,函数f的每个定义(实现)都必须采用A类型的输入参数并返回B类型的结果。
代码如下:
object Rextester extends App {
println("Hello, World!3")
}
trait Dep[C]{
type A
type B
}
trait View1
trait View2
object Dep{
type Aux[C0, A0, B0]= Dep[C0] {type A=A0; type B= B0}
implicit object DepInstanceView1 extends Dep[View1] {
type A=String
type B=Int
}
implicit object DepInstanceView2 extends Dep[View2] {
type A=String
type B=String
}
}
trait ServerSideFun[C]
{
def f[A,B] (a:A)(implicit aux:Dep.Aux[C,A,B]):B
}
object ServerSideFun {
implicit object View1Conv extends ServerSideFun[View1]{
def f[A, B] (a:A)(implicit aux:Dep.Aux[View1,A,B]):B = 42
}
implicit object View2Conv extends ServerSideFun[View2]{
def f[A, B] (a:A)(implicit aux:Dep.Aux[View2,A,B]):B = "42"
}
}
object ServerSideFunAlternativeImplementation {
implicit object View1Conv extends ServerSideFun[View1]{
def f[A, B] (a:A)(implicit aux:Dep.Aux[View1,A,B]):B = 43
}
implicit object View2Conv extends ServerSideFun[View2]{
def f[A, B] (a:A)(implicit aux:Dep.Aux[View2,A,B]):B = "43"
}
}
【问题讨论】:
-
ServerSideFun和类型级函数C -> (A, B)在您的代码中已经可以使用了。问题是这些类型级函数没有提供任何有用的定义实际值级函数f。Dep.Aux[View1, A, B]可以是任何东西。为什么42应该匹配anything?似乎Dep[C]应该是定义f(a: A): B的特征。 -
编辑的两个问题:1)
ServerSideFunAlternativeImplementation到底实现了什么?它是否应该以某种模糊的方式与ServerSideFun兼容的源代码? 2)Dep.Aux[View1, A, B]类型不限制隐式参数为" 类型级别映射View -> (A,B) 定义在对象Dep",因为额外的@ 987654372@ 可以由其他人在任何地方定义。 -
1) 根据范围内的隐式,将执行
f的不同实现。 2)嗯,有趣的一点。确实。感谢您指出了这一点。但是,在这种情况下,这将在调用代码中明确显示,类型类的用户需要采取额外的努力(偏离默认范围内的默认实现),所以在某种意义上仍然存在某种“软限制”到位。 -
1) 我不太明白你所说的“源代码兼容”是什么意思?
-
To 1): "取决于哪个隐含在范围内" -- 你首先会寻找什么隐含的type?我期待像
(impliicit ssf: ServerSideFunIntf)这样的东西,但目前ServerSideFun和ServerSideFunAlternativeImplementation除了AnyRef之外没有共同的祖先。
标签: scala types typeclass dependent-type