はじめに:
snoyman の「永続的な」ライブラリをチェックしているときに、何かを理解するのに ghci (または別のツール) の支援が必要であることに気付きました。
ghci's:info
は、「プレーン」タイプの場合ほどタイプファミリーとデータファミリーではうまく機能しないようです。
> :info Maybe
data Maybe a = Nothing | Just a -- Defined in Data.Maybe
...
> :info Persist.Key Potato -- "Key Potato" defined in example below
data family Persist.Key val -- Defined in Database.Persist
... (no info on the structure/identity of the actual instance)
ソースコードでいつでもインスタンスを探すことができますが、見つけるのが難しい場合があり、テンプレート-haskell 生成コードなどに隠されている場合があります.
コード例:
{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, TypeFamilies, QuasiQuotes #-}
import qualified Database.Persist as Persist
import Database.Persist.Sqlite as PSqlite
PSqlite.persistSqlite [$persist|
Potato
name String
isTasty Bool
luckyNumber Int
UniqueId name
|]
上記のコード例で何が起こっているかというと、ここでは Template-Haskell がコードを生成しています。上記の を除くすべての拡張機能QuasiQuotes
は、生成されたコードで使用されるため、必須です。
私は何Persist.Key Potato
をしているのかを知りました:
-- test.hs:
test = PSqlite.persistSqlite [$persist|
...
-- ghci:
> :l test.hs
> import Language.Haskell.TH
> import Data.List
> runQ test >>= putStrLn . unlines . filter (isInfixOf "Key Potato") . lines . pprint
where newtype Database.Persist.Key Potato = PotatoId Int64
type PotatoId = Database.Persist.Key Potato
質問:
ghci またはその他のツールを使用して、型ファミリおよびデータ ファミリのインスタンスに関する情報を取得する簡単な方法はありますか?