xsl example f# monads computation-expression

f# - example - xsl conditional if



Intuición detrás de llamar a Zero para la rama else if... then construir en expresiones de cálculo (1)

La documentación msdn para el método Zero en expresiones de cálculo indica que

Invocado para else ramas vacías de if...then expresiones en expresiones de cálculo.

Supongamos que estamos utilizando un identity cálculo de identity que no tiene definido Zero .

let IdentityBuilder() = member this.Bind(i, f) = f i member this.Return(i) = i let identity = new IdentityBuilder()

El código a continuación está permitido

identity { printf "Hello World" return 1 }

Sin embargo, el siguiente código no está permitido y falla con el error del compilador

Esta construcción de control solo se puede usar si el generador de expresiones de cálculo define un método ''cero''

identity { if true then printf "Hello World" return 1 }

¿Por qué el compilador insiste en llamar a Zero para las else ramas? ¿Cuál es la intuición detrás de esto?


Si una implementación de Zero es necesaria o no se determina por la forma en que la sentencia if se traduce en llamadas a funciones a partir de la sintaxis monádica. Si ambas ramas de un if son expresiones de computación sintáctica, entonces la traducción no implica Zero . En el caso de que una de las ramas no sea sintácticamente una expresión de cálculo o le falte, la expresión traducida implica Zero .

Revisaré los casos.

Tanto if como if else son expresiones sintácticamente computacionales

identity { if true then return 1 else return 2 return 1 }

se traduce a:

identity.Combine( if true then identity.Return(1) else identity.Return(2), identity.Return(1) )

Una rama falta

identity { if true then return 1 return 1 }

se traduce a:

identity.Combine( if true then identity.Return(1) else identity.Zero(), identity.Return(1) )

Ambas ramas se especifican pero no son sintácticamente expresiones de cálculo

identity { if true then printf "Hello World" else () return 1 }

se traduce a:

identity.Combine( if true then printf "Hello World" else (); identity.Zero(), identity.Return(1) )

El último caso es algo interesante porque la traducción tiene lugar incluso si la instrucción if devuelve un valor monádico válido, la traducción que utiliza Zero todavía se lleva a cabo. El último caso también se aplica a un if sin else cuando la parte then no es sintácticamente una expresión de cálculo.

EDITAR: Recientemente investigué un poco más y me di cuenta de que mi respuesta original era incorrecta.