Transformieren von Funktionen vom Typ 'a - b' in solche vom Typ 'String - String' in Haskell

7

Meine Absicht ist einfach. Ich möchte Funktionen vom Typ a -> b in String -> String umwandeln (so dass einige heterogene Funktionen in eine Liste eingefügt werden können). Also schreibe ich:

%Vor%

Allerdings ghc Beschwerden:

%Vor%

Ich möchte wissen, warum mein Code nicht funktioniert und welche Art von Hacks benötigt werden, um mein Ziel zu erreichen?

Danke.

    
tfboy 07.08.2013, 14:31
quelle

2 Antworten

13

Ihr Code wird nicht funktionieren, weil Haskell keine Variablen vom Typ "repeat" oder "scope" verwendet; Die a in wrap :: (Read a, Show b) => (a -> b) -> (String -> String) ist eine völlig andere a von der in read s :: a (und sie sind beide allgemein quantifiziert). Dies ist die Quelle von a1 in der Fehlermeldung; GHC konvertiert das Programm alphabetisch nach

%Vor%

Allerdings ist der Argumenttyp von f innerhalb von wrap festgelegt. Das einfache Entfernen der Typannotation funktioniert problemlos. Ihre Funktion wird

%Vor%

Und Sie können es verwenden:

%Vor%

Beachten Sie, dass read s einen Typ hat, den Sie nicht aufschreiben können. In Haskell 2010 (oder 98) ist die einzige Möglichkeit, dies zu umgehen, die Verwendung einer Funktion wie asTypeOf :: a -> a -> a ; asTypeOf ist nur const , aber dank seiner Typsignatur beschränkt es sein erstes zurückgegebenes Argument auf den gleichen Typ wie seinen zweiten. Dann müssten Sie natürlich eine Variable vom Typ a heraufbeschwören. Folgendes würde dafür funktionieren:

%Vor%

Um dies zu vermeiden, können Sie in GHC die Erweiterung ScopedTypeVariables ; Wenn Sie alle Typvariablen explizit mit forall qualifizieren, werden sie genau wie Wertniveausamen definiert. Dann würde dein Code

werden %Vor%

Aber denken Sie daran, dass Sie für dieses einfache Beispiel keinerlei Typanmerkungen benötigen.

    
Antal Spector-Zabusky 07.08.2013, 14:53
quelle
10

Um den Typ von read s explizit anzugeben, benötigen Sie etwas wie ScopedTypeVariables :

%Vor%

Da sich sonst die :: a Annotation innerhalb der Funktion auf einen anderen Typ bezieht als a in der Typ-Signatur (implizit bedeutet dies :: forall a. a ). Beachten Sie jedoch, dass Sie die Typ-Anmerkung auch einfach vollständig löschen können:

%Vor%

Da der Typ von read s abgeleitet werden kann. Dadurch können Sie auch den Körper zu

vereinfachen %Vor%     
shachaf 07.08.2013 14:48
quelle