Intro:
While checking out snoyman's "persistent" library I found myself wanting ghci's (or another tool) assistance in figuring out stuff.
ghci's :info
doesn't seem to work as nicely with type-families and data-families as it does with "plain" types:
> :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)
One can always look for the instance in the source code, but sometimes it could be hard to find it and it may be hidden in template-haskell generated code etc.
Code example:
{-# 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
|]
What's going on in the code example above is that Template-Haskell is generating code for us here. All the extensions above except for QuasiQuotes
are required because the generated code uses them.
I found out what Persist.Key Potato
is by doing:
-- 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
Question:
Is there an easier way to get information on instances of type families and data families, using ghci or any other tool?