Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are applicative effects?

What is the meaning of the concept of effect in effectful applicative programming?

For example, which parts of expressions below are the effects?

[(+1)] <*> [2,3]
Just (+1) <*> Nothing
like image 1000
sevo Avatar asked Sep 14 '14 20:09

sevo


2 Answers

Much confusion was caused by the unfortunate choice of names, as is quite common in Haskell (think "return", much better named "emit").

pure x is not pure, it is x that is pure, pure is just inject. It was envisioned to be used in pure f <*> a <*> b <*> ... pattern, letting us effectfully apply a pure function f.(1)

[] applicative(2) lets us "non-deterministically" apply (<*>, not $) a non-deterministic value (not two values, in your example) to a non-deterministic function; the non-determinism is the effect.(3)

In list applicative, [(+1), (+2)] is a non-deterministic function that might increment a value by 1, and also might increment it by 2. [3,4,5] is a non-deterministic value whose possible values are as listed. Just as we apply normal entities (+1) and 3 normally, with (+1) $ 3 , so can we apply non-deterministic values non-deterministically, with [(+1)] <*> [3] or [(+1),(+2)] <*> [3,4,5].

And with Maybe the possibility of failure is the effect.


(1) as the paper says, in Introduction: "we collect the values of some effectful computations, which we then use as the arguments to a pure function (:)"

(2)[] by itself is not an applicative, ([], pure :: a -> [a], (<*>) :: [a -> b] -> [a] -> [b]) is an applicative, given some (lawful) implementations of pure and (<*>). For the [] functor, there are two possibilities: an outer product-like of the standard [] Applicative instance, and an inner product-like one of the ZipList's.

(3)x is pure (as in, "Haskell is pure"); pure x stands for an effectful computation producing x without actually having any additional effect. "without an effect" refers to the law of pure x *> u == u i.e. pure x doesn't add any effect into the combined computation on top of u's contribution. But the possibility of effect is there. (One example is an idempotent side effect, like triggering an existence of a certain file in a file system: pure () by itself would also perform this effect; (pure id <*>) == id still holds, as it should.)

pure 7 :: IO Int is certainly not the pure (as in, "Haskell is pure") value 7, it is the pure value 7 in an effectful context (here, IO). Even if it does no actual action in that context, it is still in that context (IO).

On the other hand, and unrelated to the purpose of pure, of course any Haskell value is "pure" i.e. referentially transparent. getLine is a pure, referentially transparent Haskell value. It stands for / denotes an effectful I/O computation, getting an input line from a user and producing it as the result to be used by the next I/O computation in a chain.

print 7 is a pure referentially transparent Haskell value. That's not a kind of "pure" that is meant here. [1,2] is a pure value, but seen from another perspective, interpreted by the [] implementation of <*> / pure, it's treated as a nondeterministic value with two possible pure values 1 and 2. Same for [1] = pure 1. It can still be interpreted as a nondeterministic value with one possible pure value, 1.

[1,2] *> [10,20] = [10,20,10,20] ; [1] *> [10,20] = [10,20]. So unlike [1,2], [1] doesn't add any more nondeterminism into the nondeterministic computation described / denoted by [10,20] (under the standard [] Applicative implementation). But it's still a nondeterministic value; it can participate in *>, unlike 1 which can't.

We know a type by kinds of interactions it can participate in.

See also:

  • values and computations
like image 126
Will Ness Avatar answered Dec 08 '22 11:12

Will Ness


In the FP world, an effect is any type constructor such as Maybe, [], IO, etc. Effects are not to be confused with side-effects. Intuitively, an effect is an additional property of the value you're computing. Maybe Int means that your program calculates an Int with a failure effect, or [Int] means that your program calculates an Int but with a non-deterministic effect (a non-deterministic result is here modeled as a list of possible results).

Going from here, we have the terms applicative effects and monadic effects, which mean that the said effects have Applicative and Monad instances.

I can't find any authoritative information for this, it's just what I have gleaned in my experience.

like image 31
Ionuț G. Stan Avatar answered Dec 08 '22 11:12

Ionuț G. Stan