What do Haskellers mean with “IO monad is not the effect itself, but is a recipe for the effect”. Isn’t all code a recipe for making things happen?
by that logic there is no difference between a function and a partially-applied version of that function. indirection can be semantically significant (just look at transducers)
@sundarj Trying to understand what they man. What is a function of IO String different than the same function in another language that goes out in the world to fetch a string?
a function of IO String is still technically pure
it takes a value as input, and returns a value as output - nothing else
it is Haskell itself that then uses that to do the side-effect when you use it from the main
function
note i am not a Haskeller myself, so i could be a bit off here - but that is my understanding
ok, from a type perspective it’s pure. it’s just that Haskell implements the IO monad as effecting?
right
I don’t see how it helps of viewing that function as pure though. Same input, same output. Not always the case with IO or random, etc.
but to the code itself, what Haskell does with it in the end is not relevant
you could imagine replacing the IO String
with MyIO String
and the function would still work the same, right?
Purity guarantees me that I can substitute values for function calls. This is not the case with IO. So I still don’t get it.
in terms of files and http calls, you cannot gurantee referential transparency. but IO is the next best thing.. the function does not do any effects itself - it can be tested independently of whatever effect it is doing
the random functions in Haskell, however, are referentially transparent
they take an explicit seed argument
> it can be tested independently of whatever effect it is doing Can you explain this for e.g. a function that does an HTTP request?
it's like Ring response handlers. they just return {:body "foo"}
or w/e, and then Ring itself does the grunt work
those functions can then be tested like (= (:body (handler)) "foo")
, and that is independent of the actual http request stuff
of course, monads are a little more involved than plain data, but i think the same thing applies
For example:
get :: String -> IO String
get url = simpleHTTP (getRequest url) >>= getResponseBody
You say:
> it can be tested independently of whatever effect it is doing
So, how do you test this function without doing the effect? I didn’t get that.I believe Haskell only performs IO that is used from inside the main
function. if it's not called from there, it doesn't do anything
it just returns a monad
only the main
function is capable of using that monad to do anything
you could just invoke this get
function from ghci, would also work
My point is, you cannot actually test this function without calling it?
correct
i was under the impression that calling it outside of the main
function (or maybe the repl), did not do anything effectful
perhaps i am wrong
if that were true, what would the function return then?
an instance of the IO monad
with what in it?
good question
i don't know
you can of course stub the function by returning some IO value, but that’s not the same as testing the function itself
right
perhaps it just contains what should happen once it has been called from main
@borkdude this seems to confirm what i've been saying https://stackoverflow.com/a/28639600
ok, so an IO String returned from a function is the action itself, which is always the same (because it’s some sort of reified effect), but the string may be different every time you run it… This messes with my head really.
IO String is the action itself, reified, but the outcome of the action may be different, sort of?
i guess you can think of it as, every function but main
is referentially transparent
the edge of the system is not referentially transparent, because it interfaces with the outside world - but the things that are removed from the outside world are
in terms of what they take as input and produce as output
main
is different, because it is the thing that actually ends up doing the effects
i suppose you could say they are only truly referentially transparent at compile-time
http://conal.net/blog/posts/the-c-language-is-purely-functional