打印Haskell是一个纯函数吗?

时间:2017-11-16 17:52:44

标签: haskell pure-function

在Haskell中打印是一个纯函数;为什么或者为什么不?我认为这不是因为它并不总是返回与纯函数相同的值。

3 个答案:

答案 0 :(得分:5)

IO Int类型的值实际上不是Int。它更像是一张读取"嘿Haskell运行时的纸,请以这样的方式生成Int值"。这张纸是惰性的并保持不变,即使最终由运行时生成的Int不同。

通过将纸张分配给main,您可以将纸张发送到运行时。如果IO操作永远不会妨碍main,而是在某个容器中徘徊,它将永远不会被执行。

返回IO动作的函数与其他函数一样纯粹。他们总是返回同一张纸。运行时对这些指令的作用是另一回事。

如果他们 纯净,我们在改变之前必须要三思而后

foo :: (Int -> IO Int) -> IO Int
foo f = liftA2 (+) (f 0) (f 0)

foo :: (Int -> IO Int) -> IO Int
foo f = let x = f 0 in liftA2 (+) x x

答案 1 :(得分:2)

如果您只是读取纯函数的标签(一个函数,它总是在给定相同参数值的情况下评估相同的结果值,并且不会导致任何语义上可观察到的副作用或输出,例如mutable变异对象或输出到I / O设备。)然后在打印类型中思考:

putStrLn :: String -> IO ()

你会在那里找到一个技巧,它总是返回IO (),所以... ,它会产生效果。所以在Referential Transparency方面并不纯粹  例如,getLine返回IO String,但它也是纯函数。 (@interjay贡献),我想说的是,答案非常接近这个问题:

就价值问题而言,相同输入的IO ()值始终为IO ()

关于执行问题,它不是纯粹的,因为执行它 IO ()可能有副作用(在屏幕上放一个字符串,在此 案件看起来如此无辜,但有些IO可以吃核弹,而且 然后返回Int 42)

你可以通过@Ben的好方法更好地理解:

  

“有几种方法可以解释你是如何”纯粹“操纵的   现实中。一个是说IO只是一个状态monad   被穿越的国家是你外面的整个世界   program; =(所以你的Stuff - > IO DBThing函数确实有额外的功能   隐藏的论据,接收世界,并实际返回一个   DBThing与另一个世界;它总是被称为不同的   世界,这就是为什么它甚至可以返回不同的DBThing值   当用相同的东西调用时)。另一种解释是IO   DBThing值本身就是一个必要的程序;你的Haskell程序是   一个完全没有IO的完全纯函数,它返回一个不纯的程序   做IO,Haskell运行时系统(不纯)执行   程序它返回。“

和@Erik Allik:

  

因此,返回类型IO a的值的Haskell函数实际上不是   在运行时执行的函数 - 执行的内容   IO是一个值本身。所以这些功能实际上是纯粹的   它们的返回值代表非纯计算。

您可以在Understanding pure functions in Haskell with IO

找到它们

答案 2 :(得分:0)

是的,print是一个纯函数。它返回的值为IO ()类型,您可以将其视为输出传入的字符串的一堆代码。对于传入的每个字符串,它总是返回相同的代码。