web-dev-qa-db-ja.com

なぜghcidesugarタイプリストとタイプファミリーなのですか?これを選択的に無効にすることはできますか?

ライブラリのタイプ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

さて、LotsOfStringsを使用してタイプをghciに要求すると、次のようになります。

ghci> :t undefined :: Container LotsOfStrings

ghciは素晴らしいです、そして私にかなりの結果を与えます:

undefined :: Container LotsOfStrings

しかし、Replicatedバージョンを要求すると、

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

ghciは、型同義語の代わりに型族を使用しなかった場合、型族の代わりに使用します。

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

なぜghciは型族の代わりをしているのに、型同義語をやっていないのですか? ghciがいつ置換を行うかを制御する方法はありますか?

93
Mike Izbicki

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

ghci>:kind(Container '[String、String、String、String、String])

与える:

(コンテナ '[String、String、String、String、String]):: *

一方

ghci>:kind! (コンテナ '[String、String、String、String、String])

次のようなものを印刷します:

コンテナ

(( ':)

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

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

2
user2141650

これは、今後のGHC7.8で修正されます。

データ型がPolyKindsを使用する場合、GHC7.6は種類を出力します。ご覧のように (':) * String ('[] *)だけでなく(':) String '[]

GHC 7.8では、種類はデフォルトで表示されなくなり、データ型は予想どおりリストとしてきれいに出力されます。新しいフラグを使用できます-fprint-explicit-kinds GHC7.6のように明示的な種類を表示します。この理由はわかりません。おそらく、明示的な種類は、PolyKindsを理解するのに役立つことを目的としていました。

2
sdcvvc
import GHC.TypeLits

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

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

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