定义幻像类型 - 无法编译示例

时间:2015-09-30 16:20:44

标签: haskell types algebraic-data-types phantom-types

我正在尝试了解有关幻影类型的更多信息。我试图通过Ralf Hinze阅读Fun with Phantom Types。他正在使用我以前从未见过的关键字with,我无法编译。当我尝试这个时,我在=上得到了一个解析错误。

data Type t = RInt                    with t = Int
            | RChar                   with t = Char
            | RList (Type a)          with t = [a ]
            | RPair (Type a) (Type b) with t = (a, b)

在本文的前面,他说“with”语句并不是绝对必要的,你可以设置a = t,但我不知道如何在没有它们的情况下定义这种数据类型。以下错误:Not in scope: type variable 'a'

data Type t = RInt
            | RChar
            | RList (Type a)
            | RPair (Type a) (Type b)

我错过了什么?

2 个答案:

答案 0 :(得分:8)

虽然很难看,但是下面的内容会起作用,可能会被认为在精神上略微接近这种符号。这实际上是将GADT贬低为类型相等(似乎没有自己的扩展,所以你需要 GADTsTypeFamilies启用它们)和存在。

{-# LANGUAGE ExistentialQuantification, TypeFamilies #-}

data Type t = t ~ Int => RInt
            | t ~ Char => RChar
            | forall a. t ~ [a] => RList (Type a)
            | forall a b. t ~ (a, b) => RPair (Type a) (Type b)

答案 1 :(得分:7)

我的猜测是文章中提出的定义sans - with

data Type t = RInt
            | RChar
            | RList (Type t)
            | RPair (Type t) (Type t)

以上,从不使用参数t。确实,它是幽灵。

这意味着,例如

RInt :: Type a

任何类型a。相比之下,如果遵循with约束,则RInt :: Type t不可能t ~ Intwith

GHC中不存在{-# LANGUAGE GADTs #-} data Type t where RInt :: t ~ Int => Type t RChar :: t ~ Char => Type t RList :: t ~ [a] => Type a -> Type t RPair :: t ~ (a,b) => Type a -> Type b -> Type t 语法,但GADT扮演的角色基本相同。

with

注意每个构造函数中的data Type t where RInt :: Type Int RChar :: Type Char RList :: Type a -> Type [a] RPair :: Type a -> Type b -> Type (a,b) 如何被等式约束替换。它的基本相同,用不同的方式写成。

更紧凑,我们可以将上述内容重写为

<script type="text/javascript">
function zmiana(){
    var x = document.getElementById("rowstawka");
    x.getElementsByTagName('td')[1].innerHTML=document.getElementById('Stawka2').value;

    var y = document.getElementById("rowgodziny");
    y.getElementsByTagName('td')[1].innerHTML=document.getElementById('Godziny').value;



}
</script>

其中约束已被&#34;内联&#34;在最后的类型。