是的,Haskell 有广泛使用的建模/规范语言/技术。它们不是视觉的。
在 Haskell 中,类型给出了部分规范。有时,该规范完全确定了意义/结果,同时留下了各种实现选择。超越 Haskell 到具有依赖类型的语言,如在 Agda 和 Coq(以及其他)中,类型作为一个完整的规范更有用。
在类型不够的地方,添加正式的规范,通常采用简单的函数形式。(因此,我相信,Haskell 选择的建模语言是 Haskell 本身或“数学”的答案。)在这种形式中,您给出了一个针对清晰和简单而优化的函数定义,而不是全部为了效率。该定义甚至可能涉及不可计算的操作,例如无限域上的函数相等。然后,一步一步地,将规范转换为高效可计算的功能程序的形式。每一步都保留语义(外延),因此最终形式(“实现”)保证在语义上与原始形式(“规范”)等价。您会看到这个过程被各种名称所指,包括“
典型推导中的步骤主要是“等式推理”的应用,并增加了一些数学归纳(和共同归纳)的应用。能够执行这种简单而有用的推理首先是函数式编程语言的主要动机,它们的有效性归功于“真正的函数式编程”的“外延”性质。(术语“外延”和“真正函数式”来自 Peter Landin 的开创性论文The Next 700 Programming languages。)因此,纯函数式编程的口号曾经是“有利于等式推理”,尽管我没有听到这种描述这些天几乎一样频繁。在哈斯克尔,IO
IO
STM
)。虽然指称/非指代IO
类型有利于正确的等式推理,但IO
/ 非指称类型被设计为不利于不正确的等式推理。
我在 Haskell 工作中尽可能经常使用的从规范派生的特定版本是我所说的“语义类型类态射”(TCM)。想法是为数据类型提供语义/解释,然后使用 TCM 原则通过类型类实例确定(通常是唯一的)类型的大部分或全部功能的含义。例如,我说Image
类型的含义是作为二维空间的函数。然后,TCM 原理告诉我 、 、 、 、 和 实例的含义Monoid
,Functor
它们Applicative
对应Monad
于Contrafunctor
函数Comonad
的这些实例。这是很多具有非常简洁和引人注目的规格的图像上的有用功能!(规范是语义函数加上语义 TCM 原则必须遵守的标准类型类列表。)然而,我在如何表示图像方面拥有极大的自由,语义 TCM 原则消除了抽象泄漏。如果您想看看这个原理的一些实际例子,请查看论文Denotational design with type class morphisms。