haskell - monadologia - monadas leibniz
Desafa do-notación para mónadas (1)
Puede solicitar la salida del desugarer de GHC, sin embargo esto también desugará muchas otras sintaxis.
Primero, pondremos su código en un módulo Foo.hs
:
module Foo where
a = do x <- [3..4]
[1..2]
return (x, 42)
A continuación, le pediremos a GHC que lo compile y muestre el resultado después de la fase de desugaring:
$ ghc -c Foo.hs -ddump-ds
La salida puede parecer bastante desordenada, porque es una variante de Haskell llamada Core que se utiliza como lenguaje intermedio de GHC. Sin embargo, no es demasiado difícil de leer una vez que te acostumbras. En medio de algunas otras definiciones encontramos la tuya:
Foo.a :: [(GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)]
LclIdX
[]
Foo.a =
>>=_agg
@ GHC.Integer.Type.Integer
@ (GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)
(enumFromTo_ag7
(GHC.Integer.smallInteger 3) (GHC.Integer.smallInteger 4))
(/ (x_adf :: GHC.Integer.Type.Integer) ->
>>_agn
@ GHC.Integer.Type.Integer
@ (GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)
(enumFromTo_ags
(GHC.Integer.smallInteger 1) (GHC.Integer.smallInteger 2))
(return_aki
@ (GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)
(x_adf, GHC.Integer.smallInteger 42)))
El núcleo no es muy bonito, pero poder leerlo es muy útil cuando se trabaja con GHC, ya que puede leer el volcado después de las etapas posteriores para ver cómo GHC está optimizando su código.
Si eliminamos los sufijos _xyz
agregados por el renombrador, así como las aplicaciones de tipo @ Xyz
y las llamadas a GHC.Integer.smallInteger
, y hacemos que los operadores se GHC.Integer.smallInteger
a GHC.Integer.smallInteger
, te quedas con algo como esto:
Foo.a :: [(GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)]
Foo.a = enumFromTo 3 4 >>= /x -> enumFromTo 1 2 >> return (x, 42)
Mientras estoy aprendiendo Haskell, me estoy dando cuenta de que la notación es solo azúcar sintética:
a = do x <- [3..4]
[1..2]
return (x, 42)
Se traduce como
a = [3..4] >>= (/x -> [1..2] >>= (/_ -> return (x, 42)))
Me doy cuenta de que probablemente usaré notación, pero me gustaría entender qué está pasando en la traducción. Entonces, puramente por razones pedagógicas, ¿hay alguna manera para que ghc / ghci me dé las correspondientes afirmaciones vinculantes para una mónada bastante compleja escrita en do-notation?
Editar. Resulta que lambdabot en #haskell puede hacer esto:
<Guest61347> @undo do x <- [3..4] ; [1..2] ; return (x, 42)
<lambdabot> [3 .. 4] >>= / x -> [1 .. 2] >> return (x, 42)
Aquí está el código fuente del complemento Deshacer .