为什么ghci desugar类型列表和类型系列?这可以选择性地禁用吗?

时间:2013-05-02 19:35:21

标签: haskell types ghci

我正在努力使我的库的类型ghci显示尽可能直观,但在使用更高级的类型功能时遇到了很多困难。

假设我将此代码放在一个文件中:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}

import GHC.TypeLits

data Container (xs::[*]) = Container

我在ghci中加载它,然后输入以下命令:

ghci> :t undefined :: Container '[String,String,String,String,String]

不幸的是,ghci给了我相当难看的样子:

:: Container
       ((':)
          *
          String
          ((':)
             * String ((':) * String ((':) * String ((':) * String ('[] *))))))

ghci删除了类型级字符串的糖。有没有办法阻止ghci这样做并给我一个漂亮的版本?


在相关的说明中,假设我创建了一个类型级Replicate函数

data Nat1 = Zero | Succ Nat1

type family Replicate (n::Nat1) x :: [*]
type instance Replicate Zero x = '[]
type instance Replicate (Succ n) x = x ': (Replicate n x)

type LotsOfStrings = Replicate (Succ (Succ (Succ (Succ (Succ Zero))))) String

现在,当我向ghci询问使用LotsOfStrings的类型时:

ghci> :t undefined :: Container LotsOfStrings

ghci很好,给了我很好的结果:

undefined :: Container LotsOfStrings

但如果我要求Replicate d版本,

ghci> :t undefined :: Container (Replicate (Succ (Succ (Succ (Succ (Succ Zero))))) String)

ghci在类型同义词中替换为类型族:

:: Container
       ((':)
          *
          [Char]
          ((':)
             * [Char] ((':) * [Char] ((':) * [Char] ((':) * [Char] ('[] *))))))

为什么ghci要替换类型系列,而不是类型同义词?有没有办法控制ghci何时进行替换?

3 个答案:

答案 0 :(得分:2)

我所知道的解决方法是使用:kind。例如,

  

ghci的> :kind(Container'[String,String,String,String,String])

给出:

  

(Container'[String,String,String,String,String]):: *

虽然

  

ghci的> :类! (Container'[String,String,String,String,String])

将打印出类似的内容:

  

容器

     

((':)

  *
  [Char]
  ((':)
     * [Char] ((':) * [Char] ((':) * [Char] ((':) * [Char] ('[] *))))))

正式地,当然,你问ghci与kind有不同的问题,但它有效。无论如何,使用undefined ::是一种解决方法,所以我认为这可能就足够了。

答案 1 :(得分:2)

这在即将发布的GHC 7.8中已得到修复。

如果数据类型使用PolyKinds,GHC 7.6会打印种类。因此,您看到(':) * String ('[] *)而非(':) String '[]

在GHC 7.8中,默认情况下不再显示各种类型,并且您的数据类型将按照您的预期打印为列表。您可以使用新标记-fprint-explicit-kinds来查看GHC 7.6中的显式类型。我不知道造成这种情况的原因,可能是明确的种类是为了帮助理解PolyKinds。

答案 2 :(得分:0)

import GHC.TypeLits

data Container (xs::[*]) = Container

我在ghci中加载它,然后输入以下命令:

:t undefined :: Container '[String,String,String,String,String]