bub*_*ubu 7 io monads haskell pure-function io-monad
在Haskell中打印是一个纯函数; 为什么或者为什么不?我认为这不是因为它并不总是返回与纯函数应该相同的值.
类型的IO Int
值不是真的Int
.它更像是一张纸,上面写着"嘿Haskell运行时,请以Int
这样的方式生成一个值".这张纸是惰性的并且保持不变,即使Int
最终由运行时产生的s不同.
您可以通过将纸张分配给运行时将其发送到运行时main
.如果IO
动作永远不会妨碍main
并且反而在某个容器内部萎缩,那么它将永远不会被执行.
返回IO
动作的函数与其他函数一样纯粹.他们总是返回同一张纸.运行时对这些指令的作用是另一回事.
如果它们不纯净,我们在改变之前必须要三思
foo :: (Int -> IO Int) -> IO Int
foo f = liftA2 (+) (f 0) (f 0)
Run Code Online (Sandbox Code Playgroud)
至
foo :: (Int -> IO Int) -> IO Int
foo f = let x = f 0 in liftA2 (+) x x
Run Code Online (Sandbox Code Playgroud)
如果您刚刚阅读纯函数的标签(在给定相同参数值的情况下始终计算出相同结果值的函数,并且不会导致任何语义上可观察到的副作用或输出,例如可变对象或输出的突变) I/O 设备。)然后考虑打印类型:
\n\nputStrLn :: String -> IO ()\n
Run Code Online (Sandbox Code Playgroud)\n\n你会在那里发现一个技巧,它总是返回IO ()
,所以......不,它会产生效果。所以就引用透明度而言不是纯粹的\n例如,getLine
返回IO String
但它也是一个纯函数。(@interjay 贡献),我想说的是,答案取决于问题:
就值而言,相同的输入IO ()
将始终具有相同的值。IO ()
和
\n\n就执行而言,它不是纯粹的,因为执行可能IO ()
会产生副作用(在屏幕中放置一个字符串,在这种情况下看起来很无辜,但某些 IO 可能会发射核弹,然后返回 Int 42)
您可以通过@Ben 的好方法更好地理解这里:
\n\n\n\n\n“有几种方法可以解释你如何“纯粹”操纵\n现实世界。一种说法是,IO 就像一个状态单子,只是\n所穿过的状态是你\n之外的整个世界\n n program;= (所以你的 Stuff -> IO DBThing 函数确实有一个额外的\n隐藏参数来接收世界,并且实际上返回一个\n DBThing以及另一个世界;它总是用不同的\n世界来调用,这就是为什么即使使用相同的东西调用时它也可以返回不同的 DBThing 值。另一种解释是 IO DBThing 值本身就是一个命令式程序;你的 Haskell 程序是完全纯函数,不执行任何操作IO,它返回一个执行 IO 的不纯程序,Haskell 运行时系统(不纯地)执行它返回的程序。”
\n
还有@Erik Allik:
\n\n\n\n\n因此,返回 IO a 类型值的 Haskell 函数实际上不是在运行时执行的函数 \xe2\x80\x94,执行的是 IO a 值本身。所以这些函数实际上是纯函数,但它们的返回值代表非纯计算。
\n
你可以在这里找到它们Understanding pure Functions in Haskell with IO
\n 归档时间: |
|
查看次数: |
688 次 |
最近记录: |