Funktionen von 'a' für 'newtype a' verwenden

7

Sagen wir, ich habe das folgende newtype :

newtype Foo = Foo Integer deriving (Eq, Show)

Gibt es eine prägnante Möglichkeit zwei Foo 's hinzuzufügen:

(Foo 10) + (Foo 5) == Foo 15

oder holen Sie sich das Maximum:

max (Foo 10) (Foo 5) == Foo 5 ?

Ich bin neugierig, ob es möglich ist, Funktionen von a für ein newtype a zu verwenden, anstatt:

%Vor%     
Kevin Meredith 06.10.2014, 02:35
quelle

4 Antworten

12

Genau wie haskell98 diese Eq und Show Instanzen für Sie ableiten kann, können Sie die Erweiterung GeneralizedNewtypeDeriving auf ghc setzen, um die benötigten Instanzen Num und Ord zu erhalten:

%Vor%     
jberryman 06.10.2014, 03:10
quelle
10

Sie möchten Funktionen vom Typ Integer -> Integer -> Integer auf Foo -> Foo -> Foo heben. Um dies zu tun, könnten Sie Utility-Funktionen definieren:

%Vor%

Dann könnten Sie es wie folgt verwenden:

%Vor%

Dies hat den Vorteil, dass keine Erweiterung erforderlich ist.

Eine weitere Option ist, die Definition des Foo newtype zuzulassen, damit Sie eine Instanz von Functor und Applicative machen können:

%Vor%

Jetzt können Sie Folgendes tun:

%Vor%

Da foo auf den Typ Integer spezialisiert ist, verlieren Sie keine Vorteile der Typprüfung.

    
Aadit M Shah 06.10.2014 03:43
quelle
3

Sie können dafür auch safe coercions verwenden. Grob verwenden Sie Data.Coerce.coerce , um den newtype automatisch zu verpacken / auszupacken.

%Vor%

Beachten Sie, dass es bei monomorphen Funktionen wie f sehr gut funktioniert, weniger bei polymorphen Funktionen wie succ , da im letzteren Fall eine Typ-Annotation erforderlich ist.

    
chi 06.10.2014 08:24
quelle
2

Um mathematische Operationen zu erhalten, müssen Sie Foo zu einer Instanz der Num typeclass machen. Dies bedeutet, dass Sie (+) , (*) , abs , signum , fromInteger und entweder negate oder (-) für Foo definieren müssen. Sobald Sie diese Funktionen definiert haben, erhalten Sie die restlichen Funktionen, die für Num kostenlos sind.

Damit max und ähnliche Funktionen funktionieren, müssen Sie Foo eine Instanz von Ord erstellen. Dies erfordert Definitionen von compare oder (<=) .

Im Allgemeinen können Sie :t in ghci verwenden, um den Typ einer Funktion zu finden, der die typeclasses enthält, mit denen sie arbeitet. Dann müssen Sie nur bestimmen, welche minimale Menge von Funktionen Sie für diese Typklasse definieren müssen.

    
Code-Apprentice 06.10.2014 02:59
quelle

Tags und Links