Skip to content

Instantly share code, notes, and snippets.

@tonymorris
Forked from techtangents/effects.markdown
Last active December 19, 2015 14:59
Show Gist options
  • Save tonymorris/5973142 to your computer and use it in GitHub Desktop.
Save tonymorris/5973142 to your computer and use it in GitHub Desktop.

There seems to be a lot of confusion around Effects and IO. I wanted to collect a set of questions and answers, and explanations of common misconceptions.

  1. What is an Effect?

Effects come in many different shapes. In terms of monadic effects, there are different shapes again. For example, List (non-determinism), State, IO, Cont.

  1. What is a Side Effect?

An effect that is occurs to the side of the effect you are otherwise running within. In most standard environments, this is an IO effect that occurs outside of the otherwise effectful environment.

  1. What is a pure function?

One that preserves equational reasoning.

  1. What is equational reasoning?

The ability to substitute an expression with its value (and vice versa) without affecting the program in any observable way.

  1. What is an IO?

IO is a type constructor that denotes specific types of effects. It is not more special than other effectful type constructor values such as List. It is often made out to be however.

  1. Is the purpose IO value used to model an effectful computation, such that it can be composed with other computations?

I don't know what this says, so I submit: no.

  1. Is Haskell's unsafePerformIO an impure function?

Yes. It breaks equational reasoning.

  1. Related: Is it true that forall a, IO a is

Unicorn.

  1. Do the terms 'pure' and 'impure' only apply to functions?

No. Functions are always pure. If it is a function, then it is pure. If it is not pure, then it is not a function.

  1. The following Haskell functions have different semantics. In the former, getLine is evaluated once and its resulting value duplicated. In the latter, getLine is evaluated twice. These two values have the same type. Can you offer any relevant insights about the difference in these two programs, in relation to evaluation and equational reasoning? Is there anything significant about the fact that getLine is effectful that does not apply to a pure function? Is the difference in semantics inherent in the difference between the Monad implementations? a = liftM (\ a -> [a, a]) getLine b = sequence [getLine, getLine]

The getLine function is not evaluated twice. The getLine function is effectful like any other. These two programs are inequivalent as you observe and not just for IO.

  1. What other types are used to model effects?

:info Monad

  1. Are all effectful computations Monads? Are some only Functors or Applicatives?

No, I am specifically discussing monadic effects here. There are many kinds of others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment