Reputation:
What is the difference between pure and impure in haskell? When doing IO in haskell, what does it mean to keep the pure and impure items separate?
Upvotes: 14
Views: 4134
Reputation: 122519
Everything in Haskell is pure. What you are reading about is likely about code inside the IO mondad vs. outside. Once you put something into the IO monad, it can never "escape" -- you have to stay in the IO monad. Therefore, the IO monad has a tendency to "invade" your code -- if you have a thing that returns IO, then any code that calls that also has to return IO, and so on. Therefore it is best to use the IO monad only where it is necessary, at as top level of the program as possible, and separate out any parts of the computation that are pure into pure functions.
Upvotes: 4
Reputation: 10761
Essentially you want to keep as little code as possible in the "impure section". Code written in the IO monad is forever tainted with insecurity. A function with the signature IO Int
will return an integer in the IO monad, but it could on top of that send nuclear missiles to the moon. We have no way of knowing without studying every line of the code.
For example, let's say you want to write a program that takes a string and appends ", dude" to it.
main = do
line <- getLine
putStrLn $ line ++ ", dude"
Some of the parts of the code are required to be in the IO monad, because they have side effects. This includes getLine and putStrLn. However, putting the two strings together does not.
main = do
line <- getLine
putStrLn $ addDude line
addDude input = input ++ ", dude"
The signature of addDude shows that it is pure: String -> String
. No IO
here. This means we can assume that addDude will behave at least in that way. It will take one string and return one string. It is impossible for it to have side effects. It is impossible for it to blow up the moon.
Upvotes: 26
Reputation: 8448
Purity simply means causing no side-effects (reading from a disk, moving a robot arm, etc.)
Separating pure from impure functions means that you can know more about what your code is going to do. For example, when you say 1 + 2
, you know for sure by its type (Int -> Int -> Int
) that the only thing it does is take two numbers and produce a third number. If its type were Int -> Int -> IO Int
, it might move a robot arm each time it adds the two numbers.
A good starting place for the basics of Haskell can be found here: http://learnyouahaskell.com/introduction#so-whats-haskell
Upvotes: 6