简体   繁体   English

Haskell中的单例类型

[英]Singleton types in Haskell

As part of doing a survey on various dependently typed formalization techniques, I have ran across a paper advocating the use of singleton types (types with one inhabitant) as a way of supporting dependently typed programming. 作为对各种依赖类型化形式化技术进行调查的一部分,我遇到了一篇论文,主张使用单例类型(具有一个居民的类型)作为支持依赖类型编程的一种方式。

Acording to this source, in Haskell, there is a separation betwen runtime values and compile-time types that can be blurred when using singleton types, due to the induced type/value isomorphism. 根据这个来源,在Haskell中,由于诱导类型/值同构,在使用单例类型时,运行时值和编译时类型之间存在分离。

My question is: How do singleton types differ from type-classes or from quoted/reified structures in this respect? 我的问题是:在这方面,单身类型与类型类或引用/具体结构有何不同?

I would also particularly appreciate some intuitive explaination with respect to the type-theoretical importance/advantages to using singleton types and to the extent to which they can emulate dependent types in general. 我还特别理解关于使用单一类型的类型 - 理论重要性/优点以及它们一般可以模拟依赖类型的程度的一些直观解释。

As you describe, singleton types are those which have only one value (let's ignore for the moment). 如您所述,单例类型只有一个值(暂时忽略 )。 Thus, the value of a singleton type has a unique type representing the value. 因此,单例类型的值具有表示该值的唯一类型。 The crux of dependent-type theory (DTT) is that types can depend on values (or, said another way, values can parameterise types). 依赖型理论(DTT)的关键在于类型可以依赖于值(或者,换句话说,值可以参数化类型)。 A type theory that allows types to depend on types can use singleton types to let types depend on singleton values. 允许类型依赖于类型的类型理论可以使用单例类型来让类型依赖于单例值。 In contrast, type classes provide ad hoc polymorphism , where values can depend on types (the other way round to DTT where types depend on values). 相反,类型类提供ad hoc多态 ,其中值可以取决于类型(另一种方式是DTT,其中类型依赖于值)。

A useful technique in Haskell is to define a class of related singleton types. Haskell中一个有用的技术是定义一类相关的单例类型。 The classic example is of natural numbers: 经典的例子是自然数:

data S n = Succ n 
data Z = Zero

class Nat n 
instance Nat Z
instance Nat n => Nat (S n)

Provided further instances aren't added to Nat , the Nat class describes singleton types whose values/types are inductively defined natural numbers. 如果未向Nat添加更多实例,则Nat类描述单值类型,其值/类型是归纳定义的自然数。 Note that, Zero is the only inhabitant of Z but the type S Int , for example, has many inhabitants (it is not a singleton); 注意, ZeroZ的唯一居民,但是例如, S Int类型有很多居民(它不是单身人士); the Nat class restricts the parameter of S to singleton types. Nat类将S的参数限制为单例类型。 Intuitively, any data type with more than one data constructor is not a singleton type. 直观地说,任何具有多个数据构造函数的数据类型都不是单例类型。

Give the above, we can write the dependently-typed successor function: 给出上述内容,我们可以编写依赖类型的后继函数:

succ :: Nat n => n -> (S n)
succ n = Succ n 

In the type signature, the type variable n can be seen as a value since the Nat n constraint restricts n to the class of singleton types representing natural numbers. 在类型签名中,类型变量n可以看作是一个值,因为Nat n约束将n限制为表示自然数的单例类型。 The return type of the succ then depends on this value, where S is parameterised by the value n . 然后, succ的返回类型取决于此值,其中S由值n参数化。

Any value that can be inductively defined can be given a unique singleton type representation. 可以归纳定义的任何值都可以被赋予唯一的单一类型表示。

A useful technique is to use GADTs to parameterise non-singleton types with singleton types (ie with values). 一种有用的技术是使用GADT来使用单例类型(即使用值)来参数化非单例类型。 This can be used, for example, to give a type-level representation of the shape of an inductively defined data type. 例如,这可以用于给出归纳定义的数据类型的形状的类型级表示。 The classic example is a sized-list: 典型的例子是大小列表:

data List n a where
   Nil :: List Z a 
   Cons :: Nat n => a -> List n a -> List (S n) a

Here the natural number singleton types parameterise the list-type by its length. 这里,自然数单例类型按其长度参数列表类型。

Thinking in terms of the polymorphic lambda calculus, succ above takes two arguments, the type n and then a value parameter of type n . 在多晶型演算的思维, succ上面有两个参数,类型n然后类型的值参数n Thus, singleton types here provides a kind of Π-type , where succ :: Πn:Nat . n -> S(n) 因此,这里的单例类型提供了一种Π类型 ,其中succ :: Πn:Nat . n -> S(n) succ :: Πn:Nat . n -> S(n) where the argument to succ in Haskell provides both the dependent product parameter n:Nat (passed as the type parameter) and then the argument value. succ :: Πn:Nat . n -> S(n)其中Haskell中succ的参数提供了依赖的乘积参数n:Nat (作为类型参数传递),然后是参数值。

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

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