scala - DOT 演算中的列表编码
解决方案
Nothing
是底层类型是 Scala - 它是一个没有成员的类型,所以你可以很容易地说它的每个成员都是其他类型的成员,而不会说谎。
就其本身Nothing
而言(作为返回类型)用于表示函数从不返回值,这通常意味着它会引发异常。如果你有任何容器/包装器/工厂/但是你调用 if of Nothing
,这意味着它不能包含包装器的版本/任何包含/产生值的东西:
List[Nothing]
- 是一个没有任何值的列表,Future[Nothing]
- 是一个循环运行或以异常结束的 FutureOption[Nothing]
- 是选项,不能包含值
当List
你决定使用Cons
+Nil
作为编码时,假设你想在没有任何奇怪的事情的情况下这样做:
sealed trait List[A]
case class Cons[A](a: head, tail: List[A]) extends List[A]
case class Nil[A]() extends List[A]
你不能简单地使用Nil
更容易使用和模式匹配的对象,因为你必须在任何地方定义它的类型。所以不幸的是,你不能拥有一个Nil
,但你需要Nil
为每种类型提供一个单独的。
Cons(1, Cons(2, Cons(3, Cons(4, Nil[Int]))))
但是,如果你做了List[A]
协变,那么 ifA
是的子类型B
thenList[A]
将是 的子类型List[B]
。
sealed trait List[+A] // notice + before A
case class Cons[+A](a: head, tail: List[A]) extends List[A]
case class Nil[+A]() extends List[A]
那么我们可以利用Nothing
成为其他所有类型的子类型:
val nil = Nil[Nothing]
Cons(1, Cons(2, Cons(3, Cons(4, nil))))
Cons("a", Cons("b", Cons("c", Cons("d", nil))))
此时,为了我们自己的方便(例如模式匹配),我们可以创建Nil
一个对象:
sealed trait List[+A]
case class Cons[+A](a: head, tail: List[A]) extends List[A]
case object Nil extends List[Nothing]
多亏了这一点,我们只需要一个Nil
,而不是每种类型的一个。
这就是它在当前 Scala (2) 中的工作方式,并且在 Dotty 中没有改变。您的示例中的 DOT 演算显示了这如何转化为形式主义:Nothing
除了您有 ⊥ 之外,其他所有内容都基本相同,但符号不同。
推荐阅读
- java - 用于为多模块 Java Maven 项目构建 Docker 映像的 Docker 文件
- javascript - 在 gpu.js 中使用变量时“未定义标识符” - 为什么?
- maven - 如何使用 brew 但没有 openjdk 安装 maven?
- php - Http 错误 500 - 不在网站上,而是在访问 PHPMailer 6.1.4 的 Oauth Gmail 配置目录中的文件时
- r - 用列折叠行数据(字符、数字、因子等)
- delphi - 从 IDE 的结构面板中,如何将 TCard 复制到剪贴板?
- java - Maven 在构建 JAR 文件时需要包含文件
- javascript - 删除 JavaScript 字符串中 2 个特定字符串之间的字符
- java - 使用 java 的 SSL 到期信息
- c++ - 如何在 C++ 容器中将元素向左移动(以实现擦除)?