Ich versuche, die Ghci-Typanzeigen für meine Bibliotheken so intuitiv wie möglich zu gestalten, aber ich habe viele Schwierigkeiten, wenn ich erweiterte Typfunktionen verwende.
Angenommen, ich habe diesen Code in einer Datei:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
import GHC.TypeLits
data Container (xs::[*]) = Container
Ich lade es in ghci hoch und gebe dann den folgenden Befehl ein:
ghci> :t undefined :: Container '[String,String,String,String,String]
Leider sieht mir ghci ziemlich hässlich aus:
:: Container
((':)
*
String
((':)
* String ((':) * String ((':) * String ((':) * String ('[] *))))))
ghci hat den Zucker für Saiten auf Typebene entfernt. Gibt es eine Möglichkeit, ghci daran zu hindern, dies zu tun und mir nur die hübsche Version zu geben?
Nehmen wir an, ich erstelle eine Replicate
Funktion auf Typebene
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
Nun, wenn ich ghci nach einem Typ frage, der Folgendes verwendet LotsOfStrings
:
ghci> :t undefined :: Container LotsOfStrings
ghci ist nett und gibt mir das hübsche Ergebnis:
undefined :: Container LotsOfStrings
Aber wenn ich nach der Replicate
d-Version frage ,
ghci> :t undefined :: Container (Replicate (Succ (Succ (Succ (Succ (Succ Zero))))) String)
ghci ersetzt die Typfamilie, wenn dies für das Typensynonym nicht der Fall ist:
:: Container
((':)
*
[Char]
((':)
* [Char] ((':) * [Char] ((':) * [Char] ((':) * [Char] ('[] *))))))
Warum ersetzt ghci die Typenfamilie, nicht aber das Typensynonym? Gibt es eine Möglichkeit zu kontrollieren, wann ghci die Substitution durchführen wird?
[Char]
und manchmal als angezeigt String
?
String->String
, wird der Typ ihres Ergebnisses als angezeigt String
. Wenn es jedoch einen Typ aus Stücken konstruieren muss, wie z. B. in "abc"
(was dasselbe ist wie 'a':'b':'c':[]
), gibt es kein Synonym, das beibehalten werden muss. Das ist reine Spekulation.
String
mit Typvariablen f a
oder vereinheitlicht [a]
wird, er [Char]
aus ähnlichen Gründen wie später angezeigt wird .