2010-04-06 31 views
5
instance Monad (Either a) where 
    return = Left 
    fail = Right 
    Left x >>= f = f x 
    Right x >>= _ = Right x 

questo codice Frag in 'baby.hs' ha causato l'errore di compilazione orribile:Perché questo codice E-monad non digita il controllo?

Prelude> :l baby 
[1 of 1] Compiling Main    (baby.hs, interpreted) 

baby.hs:2:18: 
Couldn't match expected type `a1' against inferred type `a' 
    `a1' is a rigid type variable bound by 
     the type signature for `return' at <no location info> 
    `a' is a rigid type variable bound by 
     the instance declaration at baby.hs:1:23 
In the expression: Left 
In the definition of `return': return = Left 
In the instance declaration for `Monad (Either a)' 

baby.hs:3:16: 
Couldn't match expected type `[Char]' against inferred type `a1' 
    `a1' is a rigid type variable bound by 
     the type signature for `fail' at <no location info> 
    Expected type: String 
    Inferred type: a1 
In the expression: Right 
In the definition of `fail': fail = Right 

baby.hs:4:26: 
Couldn't match expected type `a1' against inferred type `a' 
    `a1' is a rigid type variable bound by 
     the type signature for `>>=' at <no location info> 
    `a' is a rigid type variable bound by 
     the instance declaration at baby.hs:1:23 
In the first argument of `f', namely `x' 
In the expression: f x 
In the definition of `>>=': Left x >>= f = f x 

baby.hs:5:31: 
Couldn't match expected type `b' against inferred type `a' 
    `b' is a rigid type variable bound by 
     the type signature for `>>=' at <no location info> 
    `a' is a rigid type variable bound by 
     the instance declaration at baby.hs:1:23 
In the first argument of `Right', namely `x' 
In the expression: Right x 
In the definition of `>>=': Right x >>= _ = Right x 
Failed, modules loaded: none. 

perché questo accada? e come posso compilare questo codice? grazie per qualsiasi aiuto ~

vedo. e ho regolato il codice per vederlo compila:

instance Monad (Either a) where 
    return = Right 
    Left a >>= f = Left a 
    Right x >>= f = f x 

compila con successo! ma ... per un ulteriore domanda:

instance Monad (Either a) 

fa 'O un' una monade e I got 'ritorno = Destra' ... come ho potuto ottenere 'ritorno = Sinistra'? Ho provato questo, ma non è riuscito:

instance Monad (`Either` a) where 
    return = Left 
    Right a >>= f = Right a 
    Left x >>= f = f x 

o: esempio Monade (\ x -> O x a)

non compila a tutti!

+0

Un post di blog su questo: http://ro-che.blogspot.com/2008/09/haskell-puzzle-either-monad.html –

risposta

3
  1. il reso dovrebbe avere il tipo forall b. b -> Either a b, tuttavia Left ha tipo forall c. a -> Either a c. Probabilmente vuoi proprio qui.
  2. fail dovrebbe avere tipo forall b. String -> Either a b, ha comunque retto Tipo forall b. b -> Either a b, quindi se b=String che fa String -> Either a String che non rientra.
  3. >>= dovrebbe avere tipo Either a b -> (b -> Either a c) -> Either a c tuttavia Right x >>= _ = Right x restituisce sempre un valore di tipo Either a b, non Either a c.
  4. Left x >>= f = f x non funziona perché x ha tipo a, ma f ha tipo b -> c.
9

La maggior parte della confusione deriva dal fatto che Left and Right sono usati all'indietro. Considerando solo il tipo per il ritorno, il suo tipo dalla typeclass Monade è il seguente:

return :: (Monad m) => b -> m b 

Stai cercando di definire un'istanza per m = Either a, quindi ritorno dovrebbe avere tipo:

return :: b -> Either a b 

si sta definendo come sinistra, che ha tipo:

Left :: a -> Either a b 

si noti come il lato sinistro delle -> differisce.

+0

vedo.e ho regolato il codice per vedere compila: esempio Monade (entrambi a) dove ritorno = Destra Sinistra un >> = f = Sinistra a Destra x >> = f = f x compila con successo! ma ... per un'altra domanda: istanza Monad (O a) fa 'O una' una monade e ho ottenuto 'return = Right' ... come potrei ottenere 'return = Left'? Ho provato questo, ma non è riuscito: esempio Monade ('Either' a) dove ritorno = Sinistra Destra un >> = f = Destra un Sinistra x >> = f = fx o: esempio Monade (\ x -> O xa) non si compila affatto! –

+0

Non è possibile eseguire "O una a" una Monade con 'return' =' Left'. Un Haskell 'Monad' è un typeclass di un parametro (prendiamo' b'), che corrisponde al tipo dell'argomento 'return'. Questo è incompatibile con la definizione di Haskell di "Either", che è un typeclass in cui l'ultimo argomento è quello di "Right". Potresti ottenere ciò che desideri ridefinendo 'Either' con argomenti di tipo swapped, come in' data O a b = Left b | A destra, ma sarebbe incompatibile con il supporto della libreria standard sui valori di "Entrambi". –

Problemi correlati