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?