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 deif...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.