Effect under the hood

Hello everyone.

I was curious why Effect a is represented by Unit -> a under the hood. Why this level of indirection is needed?
If Effect a would by just a then pureE could be id and bindE f a could be f(a).

The same for ST a which is built the same way, accurate to types, under the hood.

Because then:

a :: Effect Unit
a = log "hello"

would print to the console right as the window gets loaded

Welcome @thesame!

Effects in PureScript are delayed such that defining an Effect and running an Effect are separate. That helps with being able to run Effects multiple times and with keeping evaluation order sane. For example,

import Effect.Random (random) -- random :: Effect Number

-- would this print the same number 5 times, or 5 different random numbers?
randomNumbers :: Effect Unit
randomNumbers = 
  for (1 .. 5) \_ -> do
    r <- random
    logShow r

One could imagine a language in which all Effects are run as soon as they’re defined, and if you wanted to delay some Effect, you have to make it take in some argument to turn it into a “function.” (So random really would need to be random :: Unit -> Effect Number in order to behave the way you expect), but that violates one of the key principles of any pure FP language: referential transparency, which means that any function call should be able to be replaced by that function’s contents and the behavior stays the same. Let’s look at an example using the imaginary language I described above

sayHi :: Effect Unit
sayHi = log "hi"

f1 = do

f2 = do
  log "hi" 
  log "hi"

f1 would output nothing at all (presumably, a single “hi” was output when defining sayHi), while f2 would output 2 "hi"s, even though the only difference between it and f1 is we substitute the name sayHi with the contents of sayHi.
If the example was PureScript instead of this imaginary language, f1 and f2 would be identical.

Since PureScript is a functionally pure language by design, it has to be referentially transparent.


@Adrielus @ntwilson thank you. Your answers are clear and explanatory.