如何在GHC.TypeLits中使用比较

时间:2013-09-05 21:28:02

标签: haskell types ghc

我在使用GHC.TypeLits时遇到了问题。考虑以下GADT:

data Foo :: Nat -> * where
  SmallFoo :: (n <= 2)  => Foo n
  BigFoo   :: (3 <= n)  => Foo n

我的理解是,现在对于每个n,类型Foo n只填充一个值(根据n的值,可以是SmallFoo或BigFoo)

但是如果我现在想要构建一个具体的实例,如下所示:

myFoo :: Foo 4
myFoo = BigFoo

然后GHC(7.6.2)吐出以下错误消息:

No instance for (3 <= 4) arising from a use of `BigFoo'
Possible fix: add an instance declaration for (3 <= 4)
In the expression: BigFoo
In an equation for `myFoo': myFoo = BigFoo

这看起来很奇怪 - 我预计会有这种类型级别nat比较的预定义实例。如何使用type level naturals在我的数据构造函数中表达这些类型的约束?

2 个答案:

答案 0 :(得分:5)

TypeLists的解算器目前不在GHC中,根据status page,有可能在10月的GHC 7.8中出现这种情况。

现在可能最好使用other packages

答案 1 :(得分:3)

这将编译type-nats分支的当前头部,该分支应该(希望)合并为7.8。

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}

module X where

import GHC.TypeLits

data Foo :: Nat -> * where
  SmallFoo :: (n <= 2)  => Foo n
  BigFoo   :: (3 <= n)  => Foo n

myFoo :: Foo 4
myFoo = BigFoo

如果将myFoo更改为Foo 1类型,则无法编译,可能是因为x <= y类约束扩展为(x <=? y) ~ 'True等式约束:

$ /Source/ghc/inplace/bin/ghc-stage1 /tmp/blah.hs
[1 of 1] Compiling X                ( /tmp/blah.hs, /tmp/blah.o )

/tmp/blah.hs:16:13:
    Couldn't match type ‛3 <=? 1’ with ‛'True’
    In the expression: BigFoo
    In an equation for ‛myFoo’: myFoo = BigFoo