The*_*kle 6 haskell functional-programming side-effects lazy-evaluation
此代码(取自Learn You A Haskell):
main = do putStr "Hey, "
putStr "I'm "
putStrLn "Andy!"
Run Code Online (Sandbox Code Playgroud)
显然是个傻瓜
main = putStr "Hey, " >>=
(\_ -> putStr "I'm " >>=
(\_ -> putStrLn "Andy!"))
Run Code Online (Sandbox Code Playgroud)
其中,正如我所理解的那样可以解释为"为了放入斯特伦"安迪!"我首先要把putStr"我是",为了做到这一点,我首先要把putStr"嘿,";
我不同意这种解释,这很烦人,因为编译器显然不会让我感到困惑.我遇到的问题是,lambdas忽略了他们的论点,在懒惰的评估期间,这种事情是不是应该被识别和短路?
此外,当然,绑定会返回IO操作,当IO操作进入main时,它会被执行.但是什么阻止它打印"嘿,安迪!我是"?我怀疑这是绑定正在做什么.
此外,类型"IO()"的IO操作如何携带足够的信息以允许运行时系统打印"嘿,我是安迪!"?IO()与IO()的不同之处在于打印"Hello World!" 或写入文件?
考虑另一个,来自monad的维基百科页面:
加糖版:
do
putStrLn "What is your name?"
name <- getLine
putStrLn ("Nice to meet you, " ++ name ++ "!")
Run Code Online (Sandbox Code Playgroud)
Desugared版本:
putStrLn "What is your name?" >>=
(\_ ->
getLine >>=
(\name ->
putStrLn ("Nice to meet you, " ++ name ++ "!")))
Run Code Online (Sandbox Code Playgroud)
类似的故事在这里
我想我只需要看看bind for IO的定义然后就会清楚了.如果有人可以帮助我逐步完成程序的实际评估,并确定副作用发生的确切时刻,那么其他有用的东西就会有所帮助.
npo*_*cop 10
阅读Simon Peyton Jones 撰写的" 解决尴尬小队 "一文.
有关相关问题,请参阅
采取任何这样的解释,包括我的一粒盐 - 没有挥手可以取代严格的同行评审论文,解释必然过度简化.
一个非常粗略的视角是>>=可以看作列表构造函数:
data IO = [Primitive]
Run Code Online (Sandbox Code Playgroud)
和IO子系统解构该main列表的值并使用该列表.即"主要is just a list. So you may want to take a look at the definition of Haskell entry point above主要,绑定"是相当无趣的.
您还可以阅读有关haskell历史的论文,并查看早期版本的IO子系统,以了解正在发生的事情.
另外看看C语言是 Conal Elliott 纯粹功能性的讽刺文章.
功能纯度的定义是非常重要的,我记得有一篇论文详细阐述了定义,但我不记得标题.
看着IO在真实Haskell的实现可能会混淆超过它启发.但是想到这样的IO定义(假设你知道GADT):
data IO a where
Return a :: IO a
Bind :: IO a -> (a -> IO b) -> IO b
PutStr :: String -> IO ()
GetLine :: IO String
instance Monad IO where
return = Return
(>>=) = Bind
putStr :: String -> IO ()
putStr = PutStr
getLine :: IO String
getLine = GetLine
Run Code Online (Sandbox Code Playgroud)
因此,当您评估程序(类型IO ())时,它所做的只是构建一个类型的数据结构,IO ()该结构描述了一旦执行它与世界的交互将如何发生.然后,您可以想象正在编写的执行引擎,例如C,并且存在所有效果发生的地方.
所以
main = do putStr "Hey, "
putStr "I'm "
putStrLn "Andy!"
Run Code Online (Sandbox Code Playgroud)
是相同的
main = Bind (PutStr "Hey, ") (\ _ -> Bind (PutStr "I'm ") (\ _ -> PutStr "Andy!"))
Run Code Online (Sandbox Code Playgroud)
它们的排序来自执行引擎的工作方式.
也就是说,我知道没有Haskell实现实际上是这样做的.真正的实现往往会落实IO与代表现实世界正在传递令牌的状态单子(这是保证测序),和原语一样putStr只是调用C函数.
| 归档时间: |
|
| 查看次数: |
948 次 |
| 最近记录: |