我想为几个不同的A
-s定义B
中的一对类型(trait Dep[C]
和C
)。例如,A=String
= B=View
C
和View1
(在隐式对象DepInstanceView1
中定义)。然后我想在类型类定义中使用这些类型级依赖项。
如何定义具有依赖输入和返回类型的函数的类型类实例(此处为ServerSideFun[View1]
)(此处在DepInstanceView1
中定义)?
换句话说,我希望有一个类型级别函数,它来自C -> (A,B)
(这里有一个这样的类型级别映射在DepInstanceView1
中定义)并在类型类中使用这个类型级别函数声明(此处为trait ServerSideFun[C]
)及其实例(此处为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 View1
trait View2
2)为每个View
- s定义一个单独的类型级别映射View -> (A,B)
,例如:
View1-> (String,Int)
中DepInstanceView1
在View2-> (String,String)
DepInstanceView2
3)可以有类型类ServerSideFun
的几种不同实现,例如:
object ServerSideFun
object ServerSideFunAlternativeImplementation
中的另一个。本质上:
ServerSideFun[C]
的所有实例应遵循View -> (A,B)
中定义的类型级别映射object Dep
。 f
,函数View
的每个定义(实现)必须采用类型为A
的输入参数并返回类型{{1}的结果}}。 以下是代码:
B
答案 0 :(得分:1)
如果ServerSideFun[C]
应该包含某些类型f: A => B
和A
的函数B
的实现,那么ServerSideFun[C]
显然必须知道类型A
和B
是,否则它必须从来自特征f
之外的某些部分组成函数ServerSideFun[C]
。但是我们可以将type A
和type B
加入ServerSideFun[C]
,然后完全放弃Dep[C]
:
trait View1
trait View2
trait ServerSideFun[C]{
type A
type B
def f(a: A): B
}
object ServerSideFun {
implicit object View1Conv extends ServerSideFun[View1] {
type A = String
type B = Int
def f(a: String): Int = 42
}
}
如果您愿意,可以重新引入Dep[C]
,然后Dep[C]
ServerSideFun[C]
延长{/ 1}}:
trait Dep[C]{
type A
type B
}
trait View1
trait View2
object Dep {
trait DepInstanceView1 extends Dep[View1] {
type A = String
type B = Int
}
}
trait ServerSideFun[C] extends Dep[C] {
def f(a: A): B
}
object ServerSideFun {
implicit object View1Conv
extends ServerSideFun[View1]
with Dep.DepInstanceView1 {
def f(a: String): Int = 42
}
}
如果f
不是某些"天然成分"完全通用的函数,然后在某些时候你必须在已知f
和A
的上下文中写下B
的正文。在体内写下具体的42
,但同时在A
从外部带来完全未指明的B
和Dep.Aux[View1,A,B]
并不起作用。