Wie kann ich den Typ einer polymorphen Funktion für eine bestimmte Klasseninstanz erhalten?

7

Wenn Sie beispielsweise :t ap in GHCi eingeben, erhalten Sie das Ergebnis

%Vor%

Wenn ich bereits die Monad-Instanz kenne, die ich verwenden werde, ist ((->) r) , wie kann ich den Typ von ap für diese bestimmte Instanz abfragen?

    
rubystallion 24.03.2017, 12:12
quelle

3 Antworten

9

Sie können Anwendung vom sichtbaren Typ verwenden Feature zur Angabe parametrischer Typen. Sie können Funktionen auf kreativere Weise betrachten: Funktionen in Haskell können nicht nur auf Werte bestimmter Typen angewendet werden, sondern auch auf Typen dieser Werte. Aber um den Typ zu übergeben, sollten Sie irgendwie (mit dem Voranstellen von @ ) angeben, dass Sie Typen übergeben (weil Typen in Haskell noch keine erstklassigen Objekte sind).

Also hier, wie es funktioniert:

%Vor%

Die einzige Einschränkung dieses Ansatzes besteht darin, dass Sie keine Typvariablen in ghci verwenden können. Sie sollten bestimmte Typen verwenden ( Int anstelle von r ), aber das ist keine große Sache.

ERWEITERTE SEKTION

Nun, eigentlich können Sie das, aber es ist schwierig:

%Vor%

UPD: Sie können tatsächlich Platzhalter anstelle von Variablen verwenden (siehe eine andere Antwort ). Wenn Sie jedoch genaue Namen angeben möchten, verwenden Sie die Vorgehensweise von oben.

%Vor%

/ ERWEITERTE SEKTION

Noch etwas zu diesem Ansatz: Sie sollten mehr tun, wenn Ihre Funktionen mehrere Typparameter haben und Sie genau einen angeben möchten. Typen werden einzeln von links nach rechts übergeben, genauso wie einfache Argumente in einer Funktion wie bar :: Int -> String -> Double . Wenn Sie das erste Argument von bar korrigieren wollen, sollten Sie bar 5 schreiben und wenn Sie das zweite Argument reparieren wollen, dann können Sie etwas wie \n -> bar n "baz" schreiben, aber das funktioniert nicht mit dem Typ application. Sie müssen zwei Dinge wissen:

  1. Reihenfolge der Typen.
  2. So geben Sie den gewünschten Typ an.

Betrachten Sie die nächste Funktion:

%Vor%

Wir möchten Variablen vom Typ m und t angeben können. Da Haskell noch keine benannten Variablen hat, können Sie leider nicht :t lift {t=MaybeT} oder :t lift {m=IO} schreiben. Also gehe zurück zu zwei Dingen.

Um die Reihenfolge der Typen zu sehen, sollten Sie einige Compiler-Optionen verwenden. Die Reihenfolge der Typargumente wird durch forall angegeben und Sie können dies manuell tun. Andernfalls werden die Typparameter vom Compiler irgendwie sortiert. Mere Sterbliche können die Reihenfolge der Typen für lift function nicht sehen, aber wenn du dir einer höheren Magie bewusst bist, kannst du:

%Vor%

Und dann sollten Sie @_ verwenden, um einige Typen zu überspringen:

%Vor%

Nun, das ist wirklich ein Mysterium für mich, warum m als drittes Argument in forall angezeigt wird, aber als Sekunde übergeben werden sollte, aber immer noch nicht bewusst aller Magie.

    
Shersh 24.03.2017, 13:11
quelle
12

Als Lazersmoke wurde gesagt, dass Sie als Kommentar den Erweiterungen von TypeApplications , die in GHC 8.0 eingeführt wurden.

In GHCi:

%Vor%     
basile-henry 24.03.2017 13:06
quelle
2

Dies ist nur ein Hack, aber Sie könnten immer etwas tun wie:

%Vor%

oder

%Vor%

interessant

%Vor%

unterscheidet sich von

%Vor%

in dem, was ghc als das Synonym Reader r a

erkennt     
jakubdaniel 24.03.2017 12:26
quelle

Tags und Links