Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In Purescript, IO an other effects are managed with the Eff monad, and extensible effects, which are declared like this:

main :: Eff (trace :: Trace, random :: Random) {}

So if I understand well, this main declaration only allows to log to console, and generate random numbers. The trace :: Trace, random :: Random is a row of effect, ie an unordered labeled collection of effects.

Now I get that Trace is an effect, and trace is its label. But why do we need both? It makes sense for records such as { foo::String, bar::String } but I cannot understand why I would need to manage two Random effect with different labels. ie I would write the following:

main :: Eff (Trace, Random) {} -- no redundant labels

Are effect labels useful in purescript? If yes what for?

share|improve this question
    
I don't know purescript, so take my opinion with a grain of salt, but take a resource like a socket connection. In that case you might want to be able to say "give me two sockets" without caring that they start out identical, because one of them is going to connect to one place and the other another. –  Phoshi Jun 30 at 8:42

2 Answers 2

up vote 3 down vote accepted

The simple answer is that the machinery for rows already existed in the typechecker, from the very first release of the PureScript compiler, so it made sense to reuse it to define the Eff monad. The only change was to allow rows to be parameterized by the kind of the types indexed by their labels.

It certainly seems like labels are unnecessary, and they would be if effects were merely symbols. Another answer, however, is that labels allow us to keep the desirable property of having most general unifiers in the type system.

Contrived Example

Suppose you defined a handler whose type contained a row of effects with two or more unknown type variables:

runFooBarEffects :: forall eff foo bar. Eff (foo :: foo, bar :: bar | eff) a -> Eff (combined :: Baz foo bar | eff) a

And a corresponding action with concrete effect types:

myAction :: Eff (foo :: Foo, bar :: Bar, trace :: Trace) String

When we try to run this action with runFooBarEffects myAction, the typechecker correctly infers the result type Eff (combined :: Baz Foo Bar, trace :: Trace) String by unification.

However, imagine if there were no labels present. The unification algorithm would not be able to proceed, because foo could be unified with either Foo or Bar, since rows are unordered. There is no longer a most general unifier for the two rows.

This example is indeed contrived, but illustrates the point that since we are not restricted to simple atomic types (symbols) appearing in rows, but instead have a whole lattice of types, we need labels to keep the type system sane.

share|improve this answer

I have never used PureScript, but the short answer is yes, effect labels are useful for modeling effects in a principled way.

I'm not sure what your background is, so I don't know at what level to answer the question. Are you familiar with side effects, the downsides of their unrestricted use, functional programming, and why we try to avoid side effects in FP? If so, that provides a good motivation for effects systems, which make it possible to use effects without allowing their unrestricted use; in statically-typed languages, it is even possible to explicitly track effects in the type system. One popular effects system is monad transformers (of course they are not without drawbacks -- but they have already been implemented in popular languages and are therefore easy to get started experimenting with).

If you understand all of that, then perhaps your question is simply why would one need/want multiple separate instances of the same effect? Pseudo-random number generators don't generate random numbers, and the relationships between the generated numbers aren't random -- so with two (or more) separate random effects, you can essentially have two (or more) uncorrelated pseudo-random number streams.

Disclaimer: I have never used PureScript -- this is just my opinion!

Why would one need/want multiple separate instances of the same effect? Pseudo-random number generators don't generate random numbers, and the relationships between the generated numbers aren't random -- so with two (or more) separate random effects, you can essentially have two (or more) uncorrelated pseudo-random number streams.

Another benefit of using names -- even when there's no more than a single instance of any given effect -- is that some semantic meaning can be attached to the effects through a meaningful label. In other words, not all States are created equal!


Another example of using multiple instances of the same effect, check out parser combinators. These are easy to build from effects systems such as monad transformers. A simple backtracking, error-reporting parser could be built out of the:

  • State -- handles the input string
  • Error -- error-reporting
  • Maybe -- backtracking

effects (sorry, that's Haskell terminology -- I don't know how those map to PureScript's effects). If you wanted to also track the position (line, column) while parsing, you could add a second State effect. You could also track global variable declarations using a third State effect (assuming you're parsing a programming language). While in principle you could combine all three State effects into a single one, that would introduce coupling and be less extensible; having them separate avoids this coupling.

share|improve this answer
    
Thank you for your answer. I understand the need for extensible effects. My question is about their implementation in PureScript (see here). I think you are right about your multiple random effect example. I think I need to play more with the language. –  Simon Jun 30 at 16:29
    
@Simon maybe you could clarify the OP? I'm still not sure what exactly it's asking, and I'd be happy to remove or edit my answer if you wouldn't mind improving the OP. –  user39685 Jun 30 at 17:25
    
@Simon ah, I think I just got it. I initially didn't get what you meant by "label" ... I'll edit the answer when I get a chance. –  user39685 Jun 30 at 17:26
    
I have added a small example to the question. –  Simon Jun 30 at 19:30
    
@Simon gotcha -- just edited too! –  user39685 Jun 30 at 20:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.