Sto cercando di rendere i tipi visualizzati da ghci per le mie librerie il più intuitivi possibile, ma sto incontrando molte difficoltà quando utilizzo funzionalità di tipo più avanzate.
Diciamo che ho questo codice in un file:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
import GHC.TypeLits
data Container (xs::[*]) = Container
Lo carico in ghci, poi digito il seguente comando:
ghci> :t undefined :: Container '[String,String,String,String,String]
Purtroppo ghci mi dà l'aspetto piuttosto brutto:
:: Container
((':)
*
String
((':)
* String ((':) * String ((':) * String ((':) * String ('[] *))))))
ghci ha rimosso lo zucchero per le stringhe a livello di tipo. C'è un modo per impedire a ghci di farlo e di darmi solo la versione carina?
In una nota correlata, diciamo che creo una Replicate
funzione a livello di tipo
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
Ora, quando chiedo a ghci un tipo che utilizza LotsOfStrings
:
ghci> :t undefined :: Container LotsOfStrings
ghci è carino e mi dà il bel risultato:
undefined :: Container LotsOfStrings
Ma se chiedo la Replicate
versione d,
ghci> :t undefined :: Container (Replicate (Succ (Succ (Succ (Succ (Succ Zero))))) String)
ghci sostituisce il tipo family quando non lo faceva per il sinonimo di tipo:
:: Container
((':)
*
[Char]
((':)
* [Char] ((':) * [Char] ((':) * [Char] ((':) * [Char] ('[] *))))))
Perché ghci sostituisce il tipo famiglia, ma non il sinonimo del tipo? C'è un modo per controllare quando ghci effettuerà la sostituzione?
[Char]
e talvolta vengono visualizzati come String
?
String->String
, il tipo del suo risultato verrà visualizzato come String
. Tuttavia, se deve costruire un tipo da pezzi, come in eg "abc"
(che è uguale a 'a':'b':'c':[]
) non c'è nessun sinonimo da preservare. Questa è pura speculazione.
String
è unificato con variabili di tipo f a
o [a]
, verrà visualizzato come in [Char]
seguito per motivi simili.