See also questions close to this topic

I'm using the following scenario as an example to learn how to handle errors in a simple way. The scenario is basically read a file path from an environment variable, then read and print the file with the file path.

The following code works, but I don't like the printFile because it has nested case of, a bit hard to read. I wonder if there is a clean way to get rid of it and keep the printFile function flat without using lookupEnv?

Motivation : "functional programs" focus on being "pure", and we all know what "pure" is : referential transparency, "no-effects", etc...

but the problem is that this only one side of the coin.

I have not yet seen a clear definition of what an effect is.

In Haskell for example practically every non trivial "Monad" can be considered as an "effect" and there gizillion types of specific monads out there ... the problem is I don't see what is the connection between them ?

I understand intuitively that these are all "effects" but how ? Why ? What connects them ? When the values of these types (say [a]) are itself "effect-less"/pure/immutable ?

The answer I am looking for is not "anything that is not referentially transparent".

That is a "negative answer", I am looking for the opposite "type of answer", something that tells me what IS an effect and not what is it NOT.

Especially the question lies in : IO is the "ultimate" effect. Now, in what sense do we/can we/should we divide IO into "sub-effects" that are "non-interacting" => this brings us towards one possible answer: Monad Transformers. They try to solve the problem of composing effects BUT they do not themselves answer the question : what is an effect ? More importantly, how should I devide a "large/wide effect" (such as IO), into "smaller"/"narrower" effects, such as [], Future, Cont, Writer, Reader, State, Maybe etc... ?

The answer to the question : what is an effect should serve as a possible inspiration to solve problems such as the above "how to divide IO" into "sub"/simpler effects ?

I have a first list and a second list, and I want to write a function that takes two lists and returns a list containing only those elements in the second list that do not appear in the first. And I don't want to use built-in functions. For example: