2016-03-21 11 views
1

hebt Gibt es eine Möglichkeit, den Compiler zu haben, leitet die Funktionalität, die ich manuell schreiben würde:Automatische Haskell Ableiten Erklärung, dass

instance Class c => Class (Trans c) where 
    foo1 = lift foo1 
    foo2 = lift foo2 
    ... 
    foo999 = lift foo999 
    bar1 = \a b c -> lift $ bar1 a b c 
    ... 
    baz1 = lift . baz1 
    ... 

das heißt, wenn eine Art von Klasse Class in Trans gewickelt wird, ist es möglich, eine kostenlose Instanz von Class für Trans automatisch zu bekommen, ohne das schwere Heben zu tun :)?

+2

Ich bin mir nicht sicher, ich habe verstanden, was Sie eigentlich wollen. Diese Instanz wird auf allen 'c' funktionieren, also musst du sie nur einmal schreiben. Ich denke nicht, dass es im allgemeinen Fall kürzer sein kann. – chi

+0

Aber die Instanz ist langweilig (es hebt nur für alle Funktionen an), vielleicht könnte man dies kurz schreiben (indem ich nicht alle 'fooX = lift fooX' etc. aufzählen muss) – jakubdaniel

+1

Ich sehe, aber jede Alternative (zB Template Haskell) sieht schlimmer aus, es sei denn, Sie haben wirklich eine große Anzahl von Klassenmethoden. – chi

Antwort

1

Wenn lift selbst eine Typklassenfunktion ist, können Sie eine allgemeine Definition für alle Instanzen der Typklasse schreiben. Etwas wie:

instance (Class c, Trans t) => Class (t c)

Darauf achten, dass diese nicht mit anderen Fällen nicht überlappt, und ist das, was Sie für alle diese Typen wollen.

Als ein vollständigeres Beispiel funktioniert dieser Code, obwohl seine Ergebnisse manchmal überraschend sind.

{-# LANGUAGE FlexibleInstances #-} 

module Inst where 

import Control.Applicative (liftA2) 

instance (Applicative f, Num n) => Num (f n) where 
    (+) = liftA2 (+) 
    (*) = liftA2 (*) 
    abs = fmap abs 
    signum = fmap signum 
    fromInteger = pure . fromInteger 
    negate = fmap negate 
+0

Eine Instanz für die Anwendung einer Typvariablen auf etwas schreiben ist * fast nie * das Richtige Ansatz, also mag ich es nicht besonders als Vorschlag. – dfeuer

+0

Ich brauche eigentlich eine spezifische Instanz für den untersten Transformator und ich würde nur im Rest der Transformatoren heben. – jakubdaniel