(第一个注意:在我看来,正如您一直在使用的那样,“抽象”一词没有明确的含义。用于定义类型的 Isabelle 关键字可用于定义,如我所见,要么抽象或具体类型,或可以同时考虑的类型,例如'a list。)
(第二个注意:这里,我考虑了你在其他问题中与面向对象编程的比较。至于编程语言和逻辑语言,应该注意,我只是一个观察者。)
术语有类型,类型有类型(或者他们说的排序)
对我自己来说,这一切都变得模糊不清,在我看来,我不再清楚区分术语和类型,因此 Rene Thiemann 等答案有助于让我想起这一点。
不过,我知道的不多,我可以简单地认为您的短语“类型层次结构”与“类型类层次结构”同义,并且进一步与“排序层次结构”同义。这让我可以很高兴地为您的问题提供答案,尽管其他人的接受可能是不稳定的。
当然,在 Isabelle 词汇表中,类型和排序不是同义词,但在 Isabelle/HOL 中,它们是密不可分的,因为每个 HOL 术语都有一个排序。 (一个危险的说法,因为在HOL中使用了prop类型,也许我仍然不明白空排序是什么。):
-
第 3.3.4 节类型类、排序和数量,第 54 页
- isabelle.in.tum.de/website-Isabelle2014/dist/Isabelle2014/doc/isar-ref.pdf#page.54
- 空排序和
'a::type的区别
- stackoverflow.com/questions/25811989/whats-the-difference-between-the-empty-sort-a-and-a-sort-of-type-a
继承,伊莎贝尔得到了它
Isabelle 通过语言环境提供继承(以及其他方式?),其中类型类是(或包含)语言环境:
-
Section 3 Type classes as locales, page 7, classes.pdf
-
第 3 节导入,第 5 页,locales.pdf
我创建了 5 个类型类来满足您的要求,至少简单地说。每个人都有自己的身份功能。 + 符号是神奇的继承符号。
declare [[show_sorts, show_consts]]
(*The 5 type classes.*)
class cA =
fixes idA :: "'a => 'a"
assumes idA_is_id: "idA x = x"
class cB = cA +
fixes idB :: "'a => 'a"
assumes idB_is_id: "idB x = x"
class cC = cB +
fixes idC :: "'a => 'a"
assumes idC_is_id: "idC x = x"
class cD = cB +
fixes idD :: "'a => 'a"
assumes idD_is_id: "idD x = x"
class cE = cC +
fixes idE :: "'a => 'a"
assumes idE_is_id: "idE x = x"
class cF = cC +
fixes idF :: "'a => 'a"
assumes idF_is_id: "idF x = x"
有效:
(*Any of type class cB, cC, cD, and cF can be used where cA can be used.*)
term "idA (x::'a::cA)"
term "idA (x::'a::cB)"
term "idA (x::'a::cC)"
term "idA (x::'a::cD)"
term "idA (x::'a::cE)"
term "idA (x::'a::cF)"
更多继承示例:
(*Use of idC shows that cE inherited all of what's in cC.*)
term "idC :: ('a::cC => 'a::cC)"
term "idC :: ('a::cE => 'a::cE)"
term "idC (x::'a::cE)"
(*But here, there's a type sort clash, because cC didn't inherit from cE. *)
term "idE :: ('a::cC) => ('a::cC)"
现在,通过将 nat 实例化为类型类 cF 添加一些具体性:
(*It took me over an hour to see I was using 'idA_cA' instead of 'idA_nat'.
99% of the battle can be learning the syntax.*)
instantiation nat :: "{cF}"
begin
definition idA_nat :: "nat => nat" where "idA_nat == id"
definition idB_nat :: "nat => nat" where "idB_nat == id"
definition idC_nat :: "nat => nat" where "idC_nat == id"
definition idF_nat :: "nat => nat" where "idF_nat == id"
instance (*proof. Use 'proof' and see 4 subgoals: the need for 4 id functions.*)
by(default, auto simp add: idA_nat_def idB_nat_def idC_nat_def idF_nat_def)
end
(*When I instantiated nat as cF, I had to instantiate nat as cA, cB, and cC,
because I had not previously done so. Normally, you would be adding useful
'fixes' and 'assumes' with each type class, and proving useful theorems about
them.*)
value "idA (0::nat)"
value "idB (0::nat)"
value "idC (0::nat)"
value "idF (0::nat)"
(*You have to show that a type satisfies all of the 'fixes' and 'assumes'
of a type class. But additional proved theorems, you get those for free.
That's the great benefit of type classes. You may have 20 types that
you instantiate as a type class, but you only have to prove 'extraneous'
theorems once, that being for the type class, based on the 'fixes' and
'assumes' (and other things defined with other keywords).*)
我仍然会定期尝试学习如何正确使用 Isabelle 词汇。所以,我在看关键字subclass:
-
subclass,第 97 页 isar-ref.pdf
- isabelle.in.tum.de/website-Isabelle2014/dist/Isabelle2014/doc/isar-ref.pdf#page.97
我不妨证明cF 是cA 的子类,以说明一点:
context cF
begin
subclass cA ..
end
cA 是 cF 的子类,反之亦然?好吧,如果我没有在 isar-ref.pdf 中的子类定义中替换 c 和 d,我就不会已经承诺了。
它不是面向对象的类,但 C++ 在函数式编程方面无法与 ML 相比
接触语言的本质,无论是逻辑还是编程,你都会发现它们都没有给你一切,所以你最终想要它们分别给你的一切。
您可以轻松地在 C++ 中定义对象,但尝试在 C++ 中定义代数数据类型。
你可以:
- 维基代数数据类型
- en.wikipedia.org/wiki/Algebraic_data_type
- 用于 C++ 的开放且高效的类型切换
- parasol.tamu.edu/~yuriys/pm/
但这并不像 Isabelle/HOL 那样简单,它类似于 Haskell,而且我尝试过的变通方法的模式匹配能力甚至不接近。
但是,嘿,我完全支持我们想要的所有这些东西的最终融合。