Saya mencoba membuat jenis tampilan ghci untuk perpustakaan saya seintuitif mungkin, tetapi saya mengalami banyak kesulitan saat menggunakan fitur jenis yang lebih canggih.
Katakanlah saya memiliki kode ini dalam sebuah file:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
import GHC.TypeLits
data Container (xs::[*]) = Container
Saya memuatnya di ghci, lalu saya mengetik perintah berikut:
ghci> :t undefined :: Container '[String,String,String,String,String]
Sayangnya, ghci memberi saya tampilan yang agak jelek:
:: Container
((':)
*
String
((':)
* String ((':) * String ((':) * String ((':) * String ('[] *))))))
ghci telah menghilangkan gula untuk string level tipe. Apakah ada cara untuk mencegah ghci melakukan ini dan memberi saya versi yang cantik?
Pada catatan terkait, katakanlah saya membuat Replicate
fungsi level tipe
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
Sekarang, ketika saya meminta ghci untuk suatu tipe menggunakan LotsOfStrings
:
ghci> :t undefined :: Container LotsOfStrings
ghci bagus dan memberi saya hasil yang bagus:
undefined :: Container LotsOfStrings
Tetapi jika saya meminta Replicate
versi d,
ghci> :t undefined :: Container (Replicate (Succ (Succ (Succ (Succ (Succ Zero))))) String)
ghci menggantikan tipe family ketika tidak melakukannya untuk sinonim tipe:
:: Container
((':)
*
[Char]
((':)
* [Char] ((':) * [Char] ((':) * [Char] ((':) * [Char] ('[] *))))))
Mengapa ghci melakukan substitusi untuk keluarga tipe, tetapi bukan sinonim tipe? Apakah ada cara untuk mengontrol kapan ghci akan melakukan substitusi?