Is print in Haskell a pure function?

让人想犯罪 __ 提交于 2019-12-07 00:31:43

问题


Is print in Haskell a pure function; why or why not? I'm thinking it's not, because it does not always return the same value as pure functions should.


回答1:


A value of type IO Int is not really an Int. It's more like a piece of paper which reads "hey Haskell runtime, please produce an Int value in such and such way". The piece of paper is inert and remains the same, even if the Ints eventually produced by the runtime are different.

You send the piece of paper to the runtime by assigning it to main. If the IO action never comes in the way of main and instead languishes inside some container, it will never get executed.

Functions that return IO actions are pure like the others. They always return the same piece of paper. What the runtime does with those instructions is another matter.

If they weren't pure, we would have to think twice before changing

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

to:

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



回答2:


Yes, print is a pure function. The value it returns has type IO (), which you can think of as a bunch of code that outputs the string you passed in. For each string you pass in, it always returns the same code.




回答3:


If you just read the Tag of pure-function (A function that always evaluates to the same result value given the same argument value(s) and that does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices.) and then Think in the type of print:

putStrLn :: String -> IO ()

You will find a trick there, it always returns IO (), so... No, it produces effects. So in terms of Referential Transparency is not pure For example, getLine returns IO String but it is also a pure function. (@interjay contribution), What I'm trying to say, is that the answer depends very close of the question:

On matter of value, IO () will always be the same IO () value for the same input.

And

On matter of execution, it is not pure because the execution of that IO () could have side effects (put an string in the screen, in this case looks so innocent, but some IO could lunch nuclear bombs, and then return the Int 42)

You could understand better with the nice approach of @Ben here:

"There are several ways to explain how you're "purely" manipulating the real world. One is to say that IO is just like a state monad, only the state being threaded through is the entire world outside your program;= (so your Stuff -> IO DBThing function really has an extra hidden argument that receives the world, and actually returns a DBThing along with another world; it's always called with different worlds, and that's why it can return different DBThing values even when called with the same Stuff). Another explanation is that an IO DBThing value is itself an imperative program; your Haskell program is a totally pure function doing no IO, which returns an impure program that does IO, and the Haskell runtime system (impurely) executes the program it returns."

And @Erik Allik:

So Haskell functions that return values of type IO a, are actually not the functions that are being executed at runtime — what gets executed is the IO a value itself. So these functions actually are pure but their return values represent non-pure computations.

You can found them here Understanding pure functions in Haskell with IO



来源:https://stackoverflow.com/questions/47336203/is-print-in-haskell-a-pure-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!