使用隐式见证组合类型级函数
Composing type-level functions with implicit witnesses
我正在试验一些相当复杂的类型级计算。在那里,我有一些类型标签(比如 A
、B
和 C
),以及处理它们的函数,它们由具有路径相关结果类型的隐式见证表示:
class A
class B
class C
trait F1[T] { type result }
trait F2[T] { type result }
implicit object f1OfA extends F1[A] { type result = B }
implicit object f2OfB extends F2[B] { type result = C }
trait Composed[T] { type result }
在计算的过程中,当"implementing"Composed
的时候,我需要利用我可以,给定上面的代码,原则上将A
变换为C
(在这个例子中,我只需要作文,但实际上涉及的东西更多)。
但是,我不知道如何表达组合,因为我总是受限于不传递隐式的限制;以下代码因 "implicit not found":
而失败
implicit def composed1[X](implicit f2DotF1OfX: F2[F1[X]]): Composed[X] =
new Composed[X] { type result = f2DotF1OfX.result }
implicitly[Composed[C]]
我最初尝试写的是以下内容:
implicit def composed2[X](implicit f1OfX: F1[X], f2OfLast: F2[f1OfX.result]): Composed[X] =
new Composed[X] { type result = f2OfLast.result }
这当然失败了,因为我在定义的同一个参数列表中使用了 f1OfLast
。如果它不是隐式参数,我可以写
implicit def composed3a[X](f1OfX: F1[X])(f2OfLast: F2[f1OfX.result]): Composed[X] =
new Composed[X] { type result = f2OfLast.result }
但是使用两个隐式参数列表是不可能做到这一点的,因为它们在语言中是不允许的。
简而言之:在上面的例子中,我如何获得 F2[F1[X]]
的见证?如果有必要,我也可以改变写类型级函数的方式,但我还没有找到另一种表达方式。
您使用另一个类型参数然后要求 f1OfX.result
是:
implicit def composed4[X, Y](implicit f1OfX: F1[X] { type result = Y },
f2OfLast: F2[Y]): Composed[X] =
new Composed[X] { type result = f2OfLast.result }
我正在试验一些相当复杂的类型级计算。在那里,我有一些类型标签(比如 A
、B
和 C
),以及处理它们的函数,它们由具有路径相关结果类型的隐式见证表示:
class A
class B
class C
trait F1[T] { type result }
trait F2[T] { type result }
implicit object f1OfA extends F1[A] { type result = B }
implicit object f2OfB extends F2[B] { type result = C }
trait Composed[T] { type result }
在计算的过程中,当"implementing"Composed
的时候,我需要利用我可以,给定上面的代码,原则上将A
变换为C
(在这个例子中,我只需要作文,但实际上涉及的东西更多)。
但是,我不知道如何表达组合,因为我总是受限于不传递隐式的限制;以下代码因 "implicit not found":
而失败implicit def composed1[X](implicit f2DotF1OfX: F2[F1[X]]): Composed[X] =
new Composed[X] { type result = f2DotF1OfX.result }
implicitly[Composed[C]]
我最初尝试写的是以下内容:
implicit def composed2[X](implicit f1OfX: F1[X], f2OfLast: F2[f1OfX.result]): Composed[X] =
new Composed[X] { type result = f2OfLast.result }
这当然失败了,因为我在定义的同一个参数列表中使用了 f1OfLast
。如果它不是隐式参数,我可以写
implicit def composed3a[X](f1OfX: F1[X])(f2OfLast: F2[f1OfX.result]): Composed[X] =
new Composed[X] { type result = f2OfLast.result }
但是使用两个隐式参数列表是不可能做到这一点的,因为它们在语言中是不允许的。
简而言之:在上面的例子中,我如何获得 F2[F1[X]]
的见证?如果有必要,我也可以改变写类型级函数的方式,但我还没有找到另一种表达方式。
您使用另一个类型参数然后要求 f1OfX.result
是:
implicit def composed4[X, Y](implicit f1OfX: F1[X] { type result = Y },
f2OfLast: F2[Y]): Composed[X] =
new Composed[X] { type result = f2OfLast.result }