Fork me on GitHub
#other-languages
<
2017-11-24
>
borkdude11:11:31

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?

sundarj12:11:59

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)

borkdude12:11:15

@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?

sundarj12:11:14

a function of IO String is still technically pure

sundarj12:11:30

it takes a value as input, and returns a value as output - nothing else

sundarj12:11:06

it is Haskell itself that then uses that to do the side-effect when you use it from the main function

sundarj12:11:40

note i am not a Haskeller myself, so i could be a bit off here - but that is my understanding

borkdude12:11:45

ok, from a type perspective it’s pure. it’s just that Haskell implements the IO monad as effecting?

borkdude12:11:32

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.

sundarj12:11:32

but to the code itself, what Haskell does with it in the end is not relevant

sundarj12:11:33

you could imagine replacing the IO String with MyIO String and the function would still work the same, right?

borkdude12:11:24

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.

sundarj12:11:00

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

sundarj12:11:38

the random functions in Haskell, however, are referentially transparent

sundarj12:11:43

they take an explicit seed argument

borkdude12:11:56

> 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?

sundarj12:11:48

it's like Ring response handlers. they just return {:body "foo"} or w/e, and then Ring itself does the grunt work

sundarj12:11:32

those functions can then be tested like (= (:body (handler)) "foo"), and that is independent of the actual http request stuff

sundarj12:11:39

of course, monads are a little more involved than plain data, but i think the same thing applies

borkdude12:11:19

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.

sundarj12:11:16

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

sundarj12:11:39

it just returns a monad

sundarj12:11:05

only the main function is capable of using that monad to do anything

borkdude12:11:22

you could just invoke this get function from ghci, would also work

borkdude12:11:46

My point is, you cannot actually test this function without calling it?

sundarj12:11:12

i was under the impression that calling it outside of the main function (or maybe the repl), did not do anything effectful

sundarj12:11:16

perhaps i am wrong

borkdude12:11:39

if that were true, what would the function return then?

sundarj12:11:55

an instance of the IO monad

borkdude12:11:21

with what in it?

sundarj12:11:43

good question

sundarj12:11:48

i don't know

borkdude12:11:50

you can of course stub the function by returning some IO value, but that’s not the same as testing the function itself

sundarj12:11:07

perhaps it just contains what should happen once it has been called from main

sundarj12:11:29

@borkdude this seems to confirm what i've been saying https://stackoverflow.com/a/28639600

borkdude12:11:55

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.

borkdude12:11:30

IO String is the action itself, reified, but the outcome of the action may be different, sort of?

sundarj12:11:16

i guess you can think of it as, every function but main is referentially transparent

sundarj12:11:24

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

sundarj12:11:43

in terms of what they take as input and produce as output

sundarj12:11:56

main is different, because it is the thing that actually ends up doing the effects

sundarj12:11:52

i suppose you could say they are only truly referentially transparent at compile-time