我认为,我只需要看到<代码>bind>对IO
的定义,然后是明确的。
-- ghc-8.6.5/libraries/base/GHC/Base.hs; line 1381
bindIO :: IO a -> (a -> IO b) -> IO b
bindIO (IO m) k = IO ( s -> case m s of (# new_s, a #) -> unIO (k a) new_s)
-- ghc-8.6.5/libraries/base/GHC/Base.hs; line 1387
unIO :: IO a -> (State# RealWorld -> (# State# RealWorld, a #))
unIO (IO a) = a
www.un.org/Depts/DGACM/index_french.htm 在单独的模块中申报类型:
-- ghc-8.6.5/libraries/ghc-prim/GHC/Types.hs; line 169
newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
(IO
和bind
的操作者,可在查询。) How to Declare an Imperative by Philip Wadler.
如果有人能帮助我,如何实际评估该方案并确定产生副作用的确切时间,那将大有帮助。
Let s rewrite bindIO
:
http://downloads.haskell.org/%7Eghc/7.8.4/docs/html/users_guide/bang-patterns.html 取代<条码><>。
to extract the action from its first parameter using unIO
:
bindIO :: IO a -> (a -> IO b) -> IO b
bindIO m k = IO ( s -> let !(# new_s, a #) = unIO m s in unIO (k a) new_s)
现在请您扩大这一版本: 学习你 A Haskell,例如:
main = putStr "Hey, " >>=
(\_ -> putStr "I m " >>=
(\_ -> putStrLn "Andy!"))
改为:
main = bindIO (putStr "Hey, ")
(\_ -> bindIO (putStr "I m ")
(\_ -> putStrLn "Andy!"))
Now for the finicky part - expanding all the calls to bindIO
; all going well, the program would eventually resemble:
main = IO (s0 -> let !(# s1, _ #) = unIO (putStr "Hey, ") s0 in
let !(# s2, _ #) = unIO (putStr "I m ") s1 in
unIO (putStrLn "Andy!") s2)
One other change - it s optional, but it helps to clarify what s going on here:
main = IO (s0 -> let !(# s1, _ #) = unIO (putStr "Hey, ") s0 in
let !(# s2, _ #) = unIO (putStr "I m ") s1 in
let !(# s3, a3 #) = unIO (putStrLn "Andy!") s2) in
(# s3, a3 #))
-
根据我的理解,这可被解释为: 以便putStrLn “Andy<>/code>。 首先需要<代码>putStr“I m
,并为了做到这一点,我首先需要putStr “Hey,
。
Correct: because of how s0
, s1
, s2
and s3
are being used (once) in the program, which establishes an order of evaluation.
That ordering allows putStr
and putStrLn
to use effects directly
to print out their respective arguments.
So, unlike e.g. Standard ML (which uses syntactic ordering), Haskell relies on data dependencies to ensure I/O happens in the required order - the do
-notation is merely a convenience.
我面临的问题是,拉姆布达斯无视其论点,在zy评价期间,这难道是应该承认和短路的东西吗?
If we also "over-expand" your other example:
IO ( s0 -> let !(# s1, _ #) = unIO (putStrLn "What is your name?") s0 in
let !(# s2, name #) = unIO getLine s1 in
let !(# s3, a3 #) = unIO (putStrLn ("Nice to meet you, " ++ name ++ "!")) s2 in
(# s3, a3 #))
我们可以清楚地看到,实际被忽视的是outputs。 - 即<代码>(>)
http://www.un.org/Depts/DGACM/index_chinese.htm
同样的<代码>(+),(-)
和(*)
,即使其类型相同()。 Num a => a -> a-> a
- by with different name.