Why monads? How does it resolve side-effects?

后端 未结 7 891
感情败类
感情败类 2020-12-22 23:23

I am learning Haskell and trying to understand Monads. I have two questions:

  1. From what I understand, Monad is just another typeclass that declares ways to i

7条回答
  •  执念已碎
    2020-12-22 23:55

    With this concept of containers, the language essentially says anything inside the containers is non-deterministic

    No. Haskell is deterministic. If you ask for integer addition 2+2 you will always get 4.

    "Nondeterministic" is only a metaphor, a way of thinking. Everything is deterministic under the hood. If you have this code:

    do x <- [4,5]
       y <- [0,1]
       return (x+y)
    

    it is roughly equivalent to Python code

     l = []
     for x in [4,5]:
         for y in [0,1]:
             l.append(x+y)
    

    You see nondeterminism here? No, it's deterministic construction of a list. Run it twice, you'll get the same numbers in the same order.

    You can describe it this way: Choose arbitrary x from [4,5]. Choose arbitrary y from [0,1]. Return x+y. Collect all possible results.

    That way seems to involve nondeterminism, but it's only a nested loop (list comprehension). There is no "real" nondeterminism here, it's simulated by checking all possibilities. Nondeterminism is an illusion. The code only appears to be nondeterministic.

    This code using State monad:

    do put 0
       x <- get
       put (x+2)
       y <- get
       return (y+3)
    

    gives 5 and seems to involve changing state. As with lists it's an illusion. There are no "variables" that change (as in imperative languages). Everything is nonmutable under the hood.

    You can describe the code this way: put 0 to a variable. Read the value of a variable to x. Put (x+2) to the variable. Read the variable to y, and return y+3.

    That way seems to involve state, but it's only composing functions passing additional parameter. There is no "real" mutability here, it's simulated by composition. Mutability is an illusion. The code only appears to be using it.

    Haskell does it this way: you've got functions

       a -> s -> (b,s)
    

    This function takes and old value of state and returns new value. It does not involve mutability or change variables. It's a function in mathematical sense.

    For example the function "put" takes new value of state, ignores current state and returns new state:

       put x _ = ((), x)
    

    Just like you can compose two normal functions

      a -> b
      b -> c
    

    into

      a -> c
    

    using (.) operator you can compose "state" transformers

      a -> s -> (b,s)
      b -> s -> (c,s)
    

    into a single function

      a -> s -> (c,s)
    

    Try writing the composition operator yourself. This is what really happens, there are no "side effects" only passing arguments to functions.

提交回复
热议问题