[英]Desugaring do-notation for Monads
由於我正在學習哈斯克爾我意識到, do
記號只是語法糖:
a = do x <- [3..4]
[1..2]
return (x, 42)
翻譯成
a = [3..4] >>= (\x -> [1..2] >>= (\_ -> return (x, 42)))
我意識到我可能會使用do-notation,但我想了解翻譯中發生的事情。 純粹出於教學原因,ghc / ghci有沒有辦法給我一個用do-notation編寫的相當復雜的monad的相應綁定語句?
編輯。 事實證明#haskell上的lambdabot可以做到這一點:
<Guest61347> @undo do x <- [3..4] ; [1..2] ; return (x, 42)
<lambdabot> [3 .. 4] >>= \ x -> [1 .. 2] >> return (x, 42)
這是Undo插件的源代碼。
您可以詢問GHC的desugarer的輸出,但是這也會減少許多其他語法。
首先,我們將您的代碼放在Foo.hs
模塊中:
module Foo where
a = do x <- [3..4]
[1..2]
return (x, 42)
接下來,我們將要求GHC編譯它並在desugaring階段后輸出結果:
$ ghc -c Foo.hs -ddump-ds
輸出可能看起來相當混亂,因為它是Haskell的變體,稱為Core,用作GHC的中間語言。 但是,一旦你習慣它,它就不難讀。 在其他一些定義的中間我們找到你的:
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)))
Core不是太漂亮,但是在使用GHC時能夠讀取它非常有用,因為您可以在后續階段閱讀轉儲以了解GHC如何優化您的代碼。
如果我們去掉_xyz
被重命名添加的后綴,以及該類型的應用@ Xyz
和呼叫GHC.Integer.smallInteger
,並再次使運營商中綴,你留下了這樣的事情:
Foo.a :: [(GHC.Integer.Type.Integer, GHC.Integer.Type.Integer)]
Foo.a = enumFromTo 3 4 >>= \x -> enumFromTo 1 2 >> return (x, 42)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.