2011-08-19 14 views
12

Para ayudarme a aprender funcionamientos y funcionamientos aplicables, pensé que sería divertido ver cómo se implementa Either con las clases de tipos Functor y Applicative. Obviamente, podría seguir leyendo el código, pero me parece más útil intentar implementarlo por mi cuenta para comprender mejor las cosas.Intentando implementar Data.Either

FYI estoy tratando de poner en práctica la versión Haskell de los resultados de esta presentación http://applicative-errors-scala.googlecode.com/svn/artifacts/0.6/chunk-html/index.html

De todos modos, esto es lo que tengo hasta ahora

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) 

Pero cada vez que intento ejecutar esto con ghci acabo de recibir el siguiente mensaje de error: -

[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 

no estoy realmente seguro de por qué esto es, ¿alguien puede ayudar?

Respuesta

13

que estamos tratando de hacer el trabajo Functor instancia de parte Success, que es lo normal para hacer, pero debido a la orden de los parámetros de tipo que se está definiendo el tipo en la parte Failure lugar.

Puesto que usted ha definido como

data Validation a b = Success a | Failure b 

instance Functor (Validation a) where 
    ... 

Esto significa que su aplicación de fmap debe tener el tipo (x -> y) -> Validation a x -> Validation a y. Pero dado que la segunda variable de tipo es para el caso Failure, no se escribe check.

desea que la variable tipo para el caso Success a ser la última vez:

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

Ahhh veo, gracias, estoy presumiendo 'Validación de datos a b = Fracaso a | El éxito b derivado (Show, Eq) 'también sería correcto. ¡Gracias! – djhworld

+1

@djworld: Sí. Eso es exactamente lo mismo con los nombres de las variables de tipo y el orden de los constructores intercambiados. – hammar

+5

@djhworld: Y ahora también entiendes por qué, en 'O b,' izquierda 'representa el caso de falla (no solo porque no es el resultado "correcto"). –

Cuestiones relacionadas