2011-08-19 9 views
12

Per aiutarmi ad apprendere Functional Functional e Functional ho pensato che sarebbe stato divertente vedere comeè stato implementato con i typeclasses Functor e Applicative. Ovviamente potrei andare avanti e leggere il codice, ma trovo più utile provare e implementare le cose per capire meglio le cose.Cercando di implementare Data.E

FYI che sto cercando di implementare la versione Haskell dei risultati di questa presentazione http://applicative-errors-scala.googlecode.com/svn/artifacts/0.6/chunk-html/index.html

Comunque, questo è quello che ho finora

data Validation a b = Success a | Failure b deriving (Show, Eq) 

instance Functor (Validation a) where 
    fmap f (Failure x) = Failure x 
    fmap f (Success x) = Success (f x) 

Ma ogni volta che provo a fare funzionare questo con ghci Ho appena ricevuto il seguente messaggio di errore: -

[1 of 1] Compiling Main    (t.hs, interpreted) 

t.hs:5:35: 
    Couldn't match type `b' with `a1' 
     `b' is a rigid type variable bound by 
      the type signature for 
      fmap :: (a1 -> b) -> Validation a a1 -> Validation a b 
      at t.hs:4:5 
     `a1' is a rigid type variable bound by 
      the type signature for 
      fmap :: (a1 -> b) -> Validation a a1 -> Validation a b 
      at t.hs:4:5 
    Expected type: a 
     Actual type: b 
    In the return type of a call of `f' 
    In the first argument of `Success', namely `(f x)' 
    In the expression: Success (f x) 

t.hs:5:37: 
    Couldn't match type `a' with `a1' 
     `a' is a rigid type variable bound by 
      the instance declaration at t.hs:3:30 
     `a1' is a rigid type variable bound by 
      the type signature for 
      fmap :: (a1 -> b) -> Validation a a1 -> Validation a b 
      at t.hs:4:5 
    In the first argument of `f', namely `x' 
    In the first argument of `Success', namely `(f x)' 
    In the expression: Success 

Non sono proprio sicuro del motivo per cui questo può aiutare qualcuno?

risposta

13

si sta cercando di rendere il lavoro Functor istanza da parte Success, che è la cosa normale da fare, ma a causa del l'ordine dei parametri di tipo E 'in fase di definizione del tipo nella parte Failure invece.

Dal momento che avete definito come

data Validation a b = Success a | Failure b 

instance Functor (Validation a) where 
    ... 

Ciò significa che l'implementazione di fmap dovrebbe avere il tipo (x -> y) -> Validation a x -> Validation a y. Ma poiché la seconda variabile di tipo è per il caso Failure, questo non digita il controllo.

si desidera che la variabile di tipo per il caso Success di essere l'ultimo invece:

data Validation b a = Success a | Failure b 
+0

Ahhh vedo, grazie, sto presumendo 'convalida dei dati a b = Guasto a | Success b derivante (Show, Eq) 'sarebbe anche corretto. Grazie! – djhworld

+1

@djworld: Sì. Questa è la stessa cosa con i nomi delle variabili di tipo e l'ordine dei costruttori scambiati. – hammar

+5

@djhworld: E ora capisci anche perché, in 'O a b',' Left' rappresenta il caso di fallimento (non solo perché non è il risultato "giusto"). –

Problemi correlati