2012-09-05 14 views
5

Estoy interesado en conocer las decisiones de diseño por las cuales scala.Either no se hizo como una mónada. Ya existe una cierta discusión sobre la forma de derecho de polarización Either, por ejemplo:¿Por qué Scalas no es una mónada?

Pero se mencionan demasiados detalles y no pude conseguir una descripción completa sobre por qué se hace tal como se hace. ¿Puede alguien dar una visión general acerca de los beneficios de tener un Either sesgado a la derecha, sobre los problemas para hacerlo de esa manera y sobre los beneficios de no tener un Either (si es que existen)?

+0

Realmente no responde la pregunta, pero si revisa la 'Validación' de Scalaz que parece ser lo que está buscando, más o menos. – adelbertc

Respuesta

7

Creo que todo se reduce al Principle of Least Astonishment. Usar Either para codificar el éxito o el fracaso es claramente algo que la gente hace, pero no es el único uso de Either. De hecho, no hay muchas razones para que Right sea exitoso y Left sea una falla distinta de la tradición. Como menciona el comentario de adelbertc anterior, scalaz tiene Validation que codifica específicamente esto.

Para justificar aún más la demanda por encima de POLA, tome este código:

def foo(): Either[Int, Int] = Right(1) 
def bar(j: Int): Either[Int, Int] = Left(1) 
def baz(z: Int): Either[Int, Int] = Right(3) 

// Result is Left(1) 
for (a <- foo().right; b <- bar(a).right; c <- baz(b).right) yield c 

Esto compila porque estoy utilizando la proyección .right en la expresión for. Tiene sentido aquí el Left(1) en bar es el caso de falla y ese es el resultado, pero imagine si Either fue Right -biased. El código anterior se compilará sin los .right proyecciones en la expresión como:

for (a <- foo(); b <- bar(a); c <- baz(b)) yield c 

Si utilizó Either en el código para ser sólo un "uno-a-la-otra o" tipo, usted se sorprenderá por (1) el hecho de que esto compilaría y (2) devuelve Left(1) y aparentemente nunca ejecuta baz.

En resumen, use Validation si desea usar Either para codificar el éxito o el fracaso.

+0

+1 para el impresionante ejemplo. – Frank

5

No sé si esta fue la razón original, pero hay al menos una buena razón. En Scala, for las comprensiones requieren más del argumento de que es una mónada para obtener una funcionalidad completa. En particular, hay construcciones como

for (a <- ma if a > 7; /*...*/) yield /*...*/ 

que requieren que la mónada sea una (para que pueda vaciarla si la condición falla) mónada-con-cero.

Either no puede ser sensiblemente una mónada-con-cero (excepto Either[Unit,B], donde Left(()) puede ser el cero).

Una manera de hacerlo es decir: está bien, está bien, simplemente no use sus for-comprehensions de esa manera. Otra forma de hacerlo es decir: está bien, está bien, no te molestes en crear una mónada. Es una cuestión de preferencia personal, por supuesto, pero puedo ver una cierta falta de elegancia al tener Either (únicamente entre las mónadas comunes proporcionadas en Scala) caer de bruces una vez que intenta usar toda la energía que for le da.

Cuestiones relacionadas