Haskell 异常类型和数据构造函数
我不知道我怎么没有注意到这一点,但是数据构造函数和函数定义都不能将类型与Haskell 异常类型和数据构造函数,haskell,polymorphism,dependent-type,data-kinds,type-kinds,Haskell,Polymorphism,Dependent Type,Data Kinds,Type Kinds,我不知道我怎么没有注意到这一点,但是数据构造函数和函数定义都不能将类型与*以外的种类一起使用,它的变体*->*等等,这是由于(>)的种类签名,即使在-XPolyKinds下也是如此 以下是我尝试过的代码: {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} data Nat = S Nat | Z data Foo where Foo :: 'Z -> Foo -- Fails foo :: 'Z -> In
*
以外的种类一起使用,它的变体*->*
等等,这是由于(>)
的种类签名,即使在-XPolyKinds
下也是如此
以下是我尝试过的代码:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
data Nat = S Nat | Z
data Foo where
Foo :: 'Z -> Foo -- Fails
foo :: 'Z -> Int -- Fails
foo _ = 1
我得到的错误如下:
<interactive>:8:12:
Expected a type, but ‘Z’ has kind ‘Nat’
In the type signature for ‘foo’: foo :: 'Z -> Int
:8:12:
应为类型,但“Z”的种类为“Nat”
在'foo'的类型签名中:foo::'Z->Int
为什么我们不允许非传统类型的模式匹配 没有“类型的种类不是*
”这样的东西。种类*
是类型的种类,就像Int
是机器大小的数字的种类一样;其他种类可能包含与类型相似的内容,或者可以转换为类型,或者用于索引类型或其他内容,但不是类型本身,只是“类型级实体”
1通常,我在这里不考虑unbox类型。所有这些类型都是无人居住的。所以有一个问题是,为什么要进行模式匹配,具体是什么?我想我误解了
singleton
库的目标和容量。可以用其他类型索引类型。典型的例子是“Vec”:datavecna,其中Nil::vecza;缺点:a->Vec n a->Vec(S n)a
。在依赖类型的语言中,您可以编写pure:(n:Nat)->a->vecna
,但这在haskell中是不可能的,因此singleton
将自动生成类似数据SNat(n::Nat)的类型,其中SZ::SNat Z;SS::SNat n->SNat(sn)
,因此您可以“伪造”依赖类型并编写pure::SNat n->a->Vec n a
。请注意,虽然您似乎只接受种类*
的事物作为“类型”,但有许多人会将所有具有种类的事物称为“类型”(而不是“类型级实体”)。