2012-11-28 23 views
16

Zastanawiam się, czy istnieje funkcjonalność, która istnieje w GHCi (lub gdzie indziej), aby rozwinąć synonimy i rodziny z dowolnego wyrażenia typu.Rozwiń synonimy typów, wpisz rodziny z GHCi

Na przykład, jeśli mam tych typów,

data A = A 
data B = B 

data F a = F a 
data G a = G a 
data H a b = H a b 

type S a b = H (F a) (G b) 
type T a = S (a) (H B a) 

type family R a :: * 
type instance R (H a b) = H b a 

wtedy chciałbym być w stanie uzyskać tego rodzaju wyjścia w sesji ghci.

> :t undefined :: T (S B A) 
undefined :: T (S B A) :: T (S B A) 

> :texpand undefined :: T (S B A) 
undefined :: T (S B A) :: H (F ((H (F B) (G A)))) (G (H B (H (F B) (G A)))) 

> :texpand undefined :: R (T (S B A)) 
undefined :: R (T (S B A)) :: H (G (H B (H (F B) (G A)))) (F ((H (F B) (G A)))) 

O ile mogę powiedzieć, GHCi rzeczywistości nie zapewniają niczego podobnego polecenia :texpand, i nie jestem pewien, że będzie to najlepszy interfejs do tej informacji w każdym razie. Jednak wydaje się prawdopodobne, że typy rozszerzone można jakoś wyodrębnić z GHC i naprawdę chciałbym móc je zobaczyć interaktywnie.

Hacki, linki do dokumentacji, spekulacyjne dyskusje na temat przyszłych dodatków do GHCi - wszystko mile widziane.

Odpowiedz

17

:kind! zrobi, że:

λ> :kind! T (S B A) 
T (S B A) :: * 
= H (F (H (F B) (G A))) (G (H B (H (F B) (G A)))) 
λ> :kind! R (T (S B A)) 
R (T (S B A)) :: * 
= H (G (H B (H (F B) (G A)))) (F (H (F B) (G A))) 

(Dla wygody można umieścić coś takiego :def k! \x -> return (":kind! " ++ x) w swojej .ghci).

+0

Warto wspomnieć, że jest to nowy dzień GHC 7.something. (4 lub 6, zapominam) –

+3

To nie działa dla mnie w GHC 8.0.2. Po prostu wypisuje aliasy typu tak, jak jest, bez żadnego rozszerzenia. – Hjulle

+0

Mam ten sam problem z GHC 8.2.1 –