繁体   English   中英

使用Ada子类型等功能语言定义自然数

[英]Define natural numbers in functional languages like Ada subtypes

在Ada中定义自然数,您可以这样写:

subtype Natural  is Integer range 0 .. Integer'Last;

这是类型安全的,并在编译时检查。 它简单(一行代码)且效率高(它不像许多功能语言那样使用递归来定义自然数)。 有没有可以提供类似功能的功能语言?

谢谢

这是类型安全的,并在编译时检查。

正如您在问题注释中已经指出的那样,在编译时不会对其进行检查。 Modula-2或任何其他可用于生产的通用编程语言都没有等效功能。

在编译时检查此类约束的能力需要某种依赖类型,细化类型或类似构造。 您可以在定理证明者(如CoqAgda)或实验/学术语言(如ATSLiquid Haskell)中找到这类功能。

现在,我提到了Coq和Agda这些语言,它们递归地定义了它们的Nat类型,所以这不是您想要的,并且ATS是命令式语言。 这样就留下了Liquid Haskell(当然还有其他我没有提到的语言)。 Liquid Haskell是具有额外类型注释的Haskell,因此它绝对是一种功能语言。 在Liquid Haskell中,您可以定义一个MyNat类型(标准库中已经定义了一个名为Nat的类型),如下所示:

{-@ type MyNat = {n:Integer | n >= 0} @-}

然后像这样使用它:

{-@ fac :: MyNat -> MyNat @-}
fac :: Integer -> Integer
fac 0 = 1
fac n = n * fac (n-1)

如果然后尝试使用负数作为参数调用fac ,则会收到编译错误。 如果您以用户输入作为参数调用它,也将出现编译错误,除非您专门检查输入是否为非负数。 如果删除fac 0 = 1行,也会导致编译错误,因为现在下一行的n可能为0,因此在调用fac (n-1)n-1负,因此编译器将拒绝该错误。

应该指出的是,即使使用最新的类型推断技术,像这样的语言中的非平凡程序最终也将具有非常复杂的类型签名,并且您将花费大量的时间和精力通过越来越多的类型来追逐类型错误类型签名的复杂丛林,只有难以理解的类型错误才能指导您。 因此,这些功能可以为您提供安全的价格。 还应该指出,在使用图灵完整的语言的情况下,您有时必须编写运行时检查,以了解无法发生的情况,因为即使您认为应该编译器也无法证明所有内容。

类型化的球拍,一个类型的话球拍 ,有着丰富的数字亚型,它知道了相当多的封闭性(例如,两个非负数的和非负,双精确整数的和是一个准确的整数,等)。 这是一个简单的例子:

#lang typed/racket
(: f : (Nonnegative-Integer Nonnegative-Integer -> Positive-Integer))
(define (f x y)
  (+ x y 1))

类型检查是静态完成的,但是类型检查器当然不能证明有关数字子类型的所有真实事实。 例如,以下函数实际上仅返回类型为Nonnegative-Integer值,但是减法的类型规则仅允许TR得出Integer的结果类型。

> (lambda: ([x : Nonnegative-Integer] [y : Nonnegative-Integer])
    (- x (- x y)))
- : (Nonnegative-Integer Nonnegative-Integer -> Integer)
#<procedure>

St-Amour等人(在PADL 2012中出现)在“ 键入数字塔”中描述了数字的类型化拍子方法。 有通常的文件的链接在这里 ,但链接似乎在瞬间被打破。 如果您搜索标题,Google会将PDF缓存为HTML。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM