我在媒体上看到了这篇文章:https ://medium.com/@odomontois/tagless-unions-in-scala-2-12-55ab0100c2ff 。有一段代码我很难理解。文章的完整源代码可以在这里找到:https ://github.com/Odomontois/zio-tagless-err 。
代码是这样的:
trait Capture[-F[_]] {
def continue[A](k: F[A]): A
}
object Capture {
type Constructors[F[_]] = F[Capture[F]]
type Arbitrary
def apply[F[_]] = new Apply[F]
class Apply[F[_]] {
def apply(f: F[Arbitrary] => Arbitrary): Capture[F] = new Capture[F] {
def continue[A](k: F[A]): A = f(k.asInstanceOf[F[Arbitrary]]).asInstanceOf[A]
}
}
}
以下是我的问题:
- 鉴于类型是在对象中声明的,scala 编译器如何解决/处理任意类型?它似乎取决于 apply 方法参数类型,但是这与 Capture 是一个对象并且您可以有多个不同类型的 apply 调用这一事实有何关系?我遇到了这篇文章,对象中没有定义的类型声明是什么意思?但我仍然不清楚。
- 根据文章,上面的代码使用了另一个库https://github.com/alexknvl的技巧。您能否解释一下这种模式背后的想法是什么?它是干什么用的?我了解作者使用它是为了捕获登录过程中可能发生的多种类型的错误。
谢谢!
更新:
第一个问题:
根据规范,当上限缺失时,假定为 Any。因此,Arbitrary 被视为 Any,但是,它似乎与 Any 不可互换。
这编译:
object Test {
type Arbitrary
def test(x: Any): Arbitrary = x.asInstanceOf[Arbitrary]
}
但是,这不会:
object Test {
type Arbitrary
def test(x: Any): Arbitrary = x
}
Error:(58, 35) type mismatch;
found : x.type (with underlying type Any)
required: Test.Arbitrary
def test(x: Any): Arbitrary = x
另请参阅此 scala益智游戏。