93

I'm trying to make the types ghci displays for my libraries as intuitive as possible, but I'm running into a lot of difficulties when using more advanced type features.

Let's say I have this code in a file:

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

import GHC.TypeLits

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

I load it up in ghci, then I type the following command:

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

Unfortunately, ghci gives me the rather ugly looking:

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

ghci has removed the sugar for type level strings. Is there any way to prevent ghci from doing this and giving me just the pretty version?


On a related note, lets say I create a type level Replicate function

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

Now, when I ask ghci for a type using LotsOfStrings:

ghci> :t undefined :: Container LotsOfStrings

ghci is nice and gives me the pretty result:

undefined :: Container LotsOfStrings

But if I ask for the Replicated version,

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

ghci substitutes in for the type family when it didn't do that for the type synonym:

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

Why is ghci doing the substitution for the type family, but not the type synonym? Is there a way to control when ghci will do the substitution?

4

3 に答える 3

2

私が知っている回避策は、:kind を使用することです。例えば、

ghci> :kind (コンテナ '[文字列,文字列,文字列,文字列,文字列])

与えます:

(コンテナ '[文字列、文字列、文字列、文字列、文字列]) :: *

その間

ghci> :親切! (コンテナ '[文字列,文字列,文字列,文字列,文字列])

次のように出力します。

容器

((':)

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

もちろん、正式には ghci に別の質問をしていますが、うまくいきますkind。とにかく使用するundefined ::ことは一種の回避策なので、これで十分だと思いました。

于 2013-08-07T23:39:04.010 に答える
2

これは、今後の GHC 7.8 で修正されます。

データ型が PolyKinds を使用している場合、GHC 7.6 は種類を出力します。だからあなた(':) * String ('[] *)はただの代わりに見る(':) String '[].

GHC 7.8 では、種類はデフォルトで表示されなくなり、期待どおり、データ型はリストとしてきれいに出力されます。-fprint-explicit-kindsGHC 7.6 のように、新しいフラグを使用して明示的な種類を表示できます。この理由はわかりませんが、おそらく明示的な種類は、PolyKinds を理解するための助けとなることを意図していました。

于 2014-02-12T23:07:36.437 に答える
0
import GHC.TypeLits

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

ghci にロードしてから、次のコマンドを入力します。

:t undefined :: Container '[String,String,String,String,String]
于 2013-08-01T04:57:31.563 に答える