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 Replicate
d 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?
[Char]
and sometimes get displayed asString
? – Mike IzbickiString->String
, then the type of its result will be displayed asString
. However if it has to construct a type from pieces, as in e.g."abc"
(which is the same as'a':'b':'c':[]
) there's no synonym to preserve. This is pure speculation. – n. 1.8e9-where's-my-share m.String
is unified with type variablesf a
or[a]
, it will be displayed as[Char]
afterwards for similar reasons. – C. A. McCann