2013-05-02 7 views
94

Ich versuche, die Typen ghci-Anzeigen für meine Bibliotheken so intuitiv wie möglich zu machen, aber ich stoße auf viele Schwierigkeiten, wenn ich erweiterte Funktionen verwende.Warum listet ghci desugar auf und gibt Familien ein? Kann dies selektiv deaktiviert werden?

Sagen wir, ich habe diesen Code in einer Datei:

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE DataKinds #-} 
{-# LANGUAGE TypeOperators #-} 

import GHC.TypeLits 

data Container (xs::[*]) = Container 

ich es in GHCI laden, dann tippe ich den folgenden Befehl ein:

ghci> :t undefined :: Container '[String,String,String,String,String] 

Leider GHCI gibt mir das ziemlich hässlich Suche:

:: Container 
     ((':) 
      * 
      String 
      ((':) 
      * String ((':) * String ((':) * String ((':) * String ('[] *)))))) 

ghci hat den Zucker für Typ-Level-Strings entfernt. Gibt es eine Möglichkeit, ghci daran zu hindern und mir nur die hübsche Version zu geben?


Über einen entsprechenden Hinweis lässt, sage ich Replicate Funktion

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 fragen GHCI für einen Typ mit LotsOfStrings erstellen Sie eine Typ-Ebene:

ghci> :t undefined :: Container LotsOfStrings 

GHCI schön und gibt mir das hübsche Ergebnis:

Aber wenn ich fragen Sie nach der Replicate d Version,

ghci> :t undefined :: Container (Replicate (Succ (Succ (Succ (Succ (Succ Zero))))) String) 

GHCI Ersatz in der Art Familie, wenn es nicht für die Art Synonym zu tun hat:

:: Container 
     ((':) 
      * 
      [Char] 
      ((':) 
      * [Char] ((':) * [Char] ((':) * [Char] ((':) * [Char] ('[] *)))))) 

Warum tut GHCI die Ersatz für die Typfamilie, aber nicht das Typ-Synonym? Gibt es eine Möglichkeit zu kontrollieren, wann ghci die Substitution durchführt?

+7

Weil Typ Synonyme rein für den menschlichen Verzehr konzipiert sind - es macht keine Substitution, weil es anerkennt, dass Sie den Typ Synonym gemacht haben, weil Sie den Typ auf diese Weise schreiben/sehen wollten. Es macht die Ersetzung mit der Typfamilie, weil Typfamilien wirklich einen Typ berechnen/herleiten, ihn nicht anzeigen. – AndrewC

+0

Die Lösung für Ihr Problem ist in Ihrer Frage - machen Sie einen Synonym, wenn Sie abkürzen möchten. – AndrewC

+0

@AndrewC Okay, ich habe nie bemerkt, dass das eine der Unterscheidungen zwischen Typensynonymen und Familien war, aber das macht Sinn. Das lässt aber immer noch die Entartung von Typenlisten übrig. –

Antwort

0
import GHC.TypeLits 

data Container (xs::[*]) = Container 

ich es laden in GHCI, ich den folgenden Befehl geben:

:t undefined :: Container '[String,String,String,String,String] 
+0

Also ...? Du bekommst immer noch das Ergebnis entzuckert, also '' String ((':) * String ((' :) * String ((':) * ... '.) – leftaroundabout

2

Die Abhilfe, die ich kenne, wird unter Verwendung von: Art. Zum Beispiel

GHCI>: Art (Container '[String, String, String, String, String])

Gibt:

(Container' [String, String, String, String, String]) :: *

Während

ghci>: Art!(Container '[String, String, String, String, String])

Wird so etwas wie dieses Motiv:

Container

((' :)

* 
    [Char] 
    ((':) 
    * [Char] ((':) * [Char] ((':) * [Char] ((':) * [Char] ('[] *)))))) 

Offiziell fragen Sie natürlich ghi eine andere Frage mit kind, aber es funktioniert.Verwenden undefined :: i Das ist irgendwie eine Art Workaround, also dachte ich, das könnte ausreichen.

+0

Ich benutzte nur' undefined :: 'um zu geben ein einfaches Beispiel. Das eigentliche Problem ist, wenn Sie eine Fehlermeldung erhalten, die eine Art von einer Liste von tausend verschiedenen Typen hat. Es braucht Seiten, um es auszudrucken, und ist sehr schwierig zu analysieren. –

+0

Ja, fair genug habe das erkannt. Ich schulde dir eine bessere Antwort – user2141650

2

Dies wird im kommenden GHC 7.8 behoben.

GHC 7.6 druckt Arten, wenn ein Datentyp PolyKinds verwendet. So sehen Sie (':) * String ('[] *) statt nur (':) String '[].

In GHC 7.8 werden die Arten standardmäßig nicht mehr angezeigt, und Ihr Datentyp wird ziemlich gut als Liste gedruckt, wie Sie es erwarten würden. Sie können die neue Flagge -fprint-explicit-kinds verwenden, um explizite Arten wie in GHC 7.6 zu sehen. Ich kenne die Gründe dafür nicht, vermutlich waren explizite Arten eine Hilfe zum Verständnis von PolyKinds.

Verwandte Themen