我不明白什麼時候必須使用let
以及何時必須使用<-
綁定。< - 和「讓」在塊內有什麼區別?
2
A
回答
2
<-
是>>=
(bind
)其中let
是fmap
在do
塊。偷
一個例子來自here:
do x1 <- action1 x0
x2 <- action2 x1
action3 x1 x2
-- is equivalent to:
action1 x0 >>= \ x1 -> action2 x1 >>= \ x2 -> action3 x1 x2
action1
,action2
& action3
都返回某種單子,說:
action1 :: (Monad m) => a -> m b
action2 :: (Monad m) => b -> m c
action3 :: (Monad m) => b -> c -> m d
你可以重寫讓綁定這樣:
-- assume action1 & action3 are the same
-- but action2 is thus:
action2 :: b -> c
do
x1 <- action1 x0
let x2 = action2 x1
action3 x1 x2
do
x1 <- action1 x0
x2 <- return & action2 x1
action3 x1 x2
-- of course it doesn't make sense to call action2
-- an action anymore, it's just a pure function.
3
let
給出函數調用結果的名稱。
<-
將當前monad中的monadic操作的結果綁定到名稱。
它們完全不同。使用let
作爲單子之外的函數的結果,即正常的純函數。使用<-
來表示monadic的任何內容,因爲它可以「解開」monad結果,並讓您獲得其中的值。
例如:
承擔具有以下簽名
frobnicate :: String -> IO Bool
和純功能的IO功能
dothing :: Bool -> Bool
我們可以做到這一點
main :: IO()
main = do
x <- frobnicate "Hello"
let y = frobnicate "Hello"
-- z <- dothing x
let z = dothing x
return()
我們知道t因爲已經從我們的IO
運算結果中提取了Bool
(該運算運行,結果被稱爲x
,因此我們可以稍後使用它)。
我們也知道y :: IO Bool
- 該操作尚未運行,對於未來的IO操作而言,它是潛在的。所以我們可以用y
做的唯一有用的事情是稍後運行它,綁定結果並在那裏得到Bool
,但在let
之後,Bool
甚至還不存在。
第三行被註釋掉,因爲它不會編譯 - 你不能對不在相關monad中的操作進行monadic綁定。 dothing
不會返回IO
任何內容,因此您無法將其綁定到IO()
函數中。
第四行是簡單的 - z
被製成的dothing x
,其中x
物的值從運行frobnicate "Hello"
較早解開的結果。
所有這一切都僅僅是「真正的」單子操作下語法糖,使膨脹(不註釋掉部分)像
main = frobnicate "Hello" >>= (\x -> let y = frobnicate "Hello"
z = dothing x
in return())
當然這個例子是沒有意義的,但希望它可以說明在do
表示法中let
和<-
的區別。
TL; DR:使用<-
爲單名操作的結果命名,let
命名爲其他所有。
1
一個很好的例子來可視化<-
不:
do
a <- ['a'..'z']
b <- [1..3]
pure (a,b)
您可以在網上REPL在try.frege-lang.org試試這個 (您可以輸入這是一個單行:
do { a <- ['a'..'z']; b <- [1..3]; pure (a,b) }
相關問題
- 1. <?有什麼區別? echo __();和<= __();
- 2. <?有什麼區別?和<?php
- 3. <%# %>和<%= %>有什麼區別?
- 4. < - 和=在data.frame中有什麼區別?
- 5. 什麼意思是「:」在<%中:和<%=有什麼區別?
- 6. 內嵌塊和追加<div class="clear"></div>有什麼區別?
- 7. <%:和<%=和<%#在aspx中有什麼區別?
- 8. 區別<p>是什麼Javascript和ASP.net有什麼區別?</p>
- 9. (null)和<null>有什麼區別?
- 10. mysqlimport和mysql有什麼區別<dbfile.sql
- 11. <?php,<?, <?=,有什麼區別?
- 12. 模塊中@和@@有什麼區別?
- 13. 在ASP.NET WebForms中,<%:, <%=和<%#之間有什麼區別?
- 14. <?或<?php ---有什麼區別?
- 15. 在doxygen中,/// <&///有什麼區別?
- 16. <#eval和<#bind在asp.net中有什麼區別
- 17. assign()和<< - 在R中有什麼區別?
- 18. 在html5中<article>和<section>有什麼區別
- 19. 在ASP.NET MVC中,<%=和<%:?有什麼區別?
- 20. Linux內核模塊中module_init和init_module有什麼區別?
- 21. 有什麼區別`和$(Bash中有什麼區別?
- 22. OpenCL中本地和全局內存區別有什麼區別?
- 23. 在同步塊內使用Vector有什麼區別?
- 24. 有什麼區別? :和||
- 25. &&和||有什麼區別?
- 26. 「/」和「/ *」有什麼區別?
- 27. 有什麼區別:。!和:r!?
- 28. ==和===有什麼區別?
- 29. Appender和〜有什麼區別?
- 30. $ @和$ *有什麼區別?
瞭解更多實際上'let'的意思是什麼,實際上'<-'做了什麼,並且可能是關於'做'notaion。 – lisyarus