簡體   English   中英

Monads的Desugaring do-notation

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM