Haskell ';缺失';(?)编程语言中的功能?

Haskell ';缺失';(?)编程语言中的功能?,haskell,types,language-design,type-systems,Haskell,Types,Language Design,Type Systems,让我们以Haskell为例,因为它最接近我将要描述的我所知道的语言 例如,Int类型可以被视为(该类型)所有可能值的集合。 为什么我们只能使用非常特定的集合? Int,Double等。。。而不是类型系统中的所有子集 我喜欢一种可以定义任意类型的语言,比如Int大于5。有这种语言的例子吗?若否,原因为何 您正在寻找的。Idris、Agda和Coq在这一类中是众所周知的。实际上可以在Haskell中定义它,因为它基本上是一个Int加上一些语义。例如,您必须决定如何处理低于阈值的减法,如(-6)7给出

让我们以Haskell为例,因为它最接近我将要描述的我所知道的语言

例如,
Int
类型可以被视为(该类型)所有可能值的集合。 为什么我们只能使用非常特定的集合?
Int
Double
等。。。而不是类型系统中的所有子集


我喜欢一种可以定义任意类型的语言,比如
Int大于5
。有这种语言的例子吗?若否,原因为何

您正在寻找的。Idris、Agda和Coq在这一类中是众所周知的。

实际上可以在Haskell中定义它,因为它基本上是一个
Int
加上一些语义。例如,您必须决定如何处理低于阈值的减法,如
(-6)7
给出的结果。(Peano算术的一个常见约定是给0——因此在本例中,它将返回系统的最小值
6
)。您还需要选择是对
from Integer 3
进行
错误
,还是存储,比如说,
newtype IntGT5=IntGT5(可能是Int)
而不是
newtype IntGT5=IntGT5 Int
。您必须自己编写所有的typeclass实例,一旦完成,您将拥有一个合适的类型

如果你对这个问题有持久的兴趣,有两件事需要注意:和。让我告诉你一点关于后者的事

艾伦·凯(Alan Kay)发明了OOP,使其与众不同(他希望每个程序都被写成一个通信计算机网络),但事实证明,在现代世界,OOP基本上是一种进行复杂子类型化的方法。例如,“Duck-typing”是关于创建一个“交叉类型”,它包含一组真正通用的类型(比如“使用“waddle”方法的对象,使用“quack”方法的对象),其他类型都是这些类型的子类型。所以子类型是非常自然的OOP

我链接到的这篇论文指出了关于子类型的另一件有趣的事情:可以使用子类型来消除类型和值之间的区别。当然,将类型转换为值不需要子类型;例如,Python语言中已经存在这种情况,您可以调用
type(x)
来获取表示对象类型的对象。但有趣的是,随着子类型的发展,您可以定义一个类型
3::Int
3
类型
Int
),它是所有
Int
的类型,这些类型等于
3
。它本质上是一个单元/空类型,是一个更大类的子类型。通过模糊类型
Int
3
和类型
Int
3
之间的区别,您可以得到每个值也是一个类型。然后,您可以使用这种方法执行类似JSON的操作,其中
{x:Int,y:3::Int}
是一种对象类型,包含两个属性
x
y
,其中
x
是任意
Int
,而
y
是整数
3::Int
支持范围内的数字类型。我不能对这种语言做出明智的评论,但我已经被了解它的人引导到理解范围检查是由编译器插入的运行时检查强制执行的

关系数据库理论也有与此相关的概念。属性可以接受的值集是它的,它是其数据类型及其上的值的函数。然而,实际的RDBMS通常不能完全实现这些概念

依赖类型是一个更通用的系统,可以对这种约束和其他许多约束进行编码。我对依赖类型的解释是这样的:它们是设计一种编程语言的方法,其中包含证明作为一级值。证明是一种价值观,凭借它的存在和它所遵循的规则,它保证命题的真实性(又称“句子”、“陈述”等)

因此,在依赖类型下,可以有一个类型
x>5
,其值证明
x
大于5。如果您有此类型的实际值,那么
x
确实大于5,因此此证明范围内的代码可以在该假设下安全地继续。您可以使用我们可以标记为
∃x:Int.x>5
,其值成对,以便:

  • 第一个元素是一个整数
    x
  • 第二个元素是
    x>5

  • @西德妮:试着用这些语言中的一种编程。这并不是说不可行,但你开始考虑太多的证明,以至于你几乎再也无法进入实际的编程部分。。。至少这是我迄今为止的经验,尽管我认为自己在制作数学美等方面是相当坚韧的。这就是为什么它们很少在实践中使用。也许依赖类型实际上应该被更多地使用,但我怀疑Agda、Idris或类似的产品在可预见的未来是否会出现。Coq领先;Haskell本身在GHC扩展中变得越来越“依赖”。有比完全依赖类型更小的系统可以实现这里所期望的功能。例如,精炼类型是液体哈斯克尔。@leftaroundabout,你读过吗?如果您使用依赖类型的语言,并且不需要依赖类型来解决某些问题,请不要使用它们。您可以关闭终止检查器,使用
    Type:Type
    (在Agda中)(Coq和Idris具有典型的模糊性,这对于用户来说几乎是看不见的),假设
    未定义
    ,并执行任何其他操作以获得普通函数式语言,另一方面,在一种类型不好的语言中强制使用某些不变量是一个非常困难的问题