What is a monad?

前端 未结 30 1670
太阳男子
太阳男子 2020-11-30 13:39

Having briefly looked at Haskell recently, what would be a brief, succinct, practical explanation as to what a monad essentially is?

I have found most expla

30条回答
  •  孤街浪徒
    2020-11-30 14:13

    After much striving, I think I finally understand the monad. After rereading my own lengthy critique of the overwhelmingly top voted answer, I will offer this explanation.

    There are three questions that need to be answered to understand monads:

    1. Why do you need a monad?
    2. What is a monad?
    3. How is a monad implemented?

    As I noted in my original comments, too many monad explanations get caught up in question number 3, without, and before really adequately covering question 2, or question 1.

    Why do you need a monad?

    Pure functional languages like Haskell are different from imperative languages like C, or Java in that, a pure functional program is not necessarily executed in a specific order, one step at a time. A Haskell program is more akin to a mathematical function, in which you may solve the "equation" in any number of potential orders. This confers a number of benefits, among which is that it eliminates the possibility of certain kinds of bugs, particularly those relating to things like "state".

    However, there are certain problems that are not so straightforward to solve with this style of programming. Some things, like console programming, and file i/o, need things to happen in a particular order, or need to maintain state. One way to deal with this problem is to create a kind of object that represents the state of a computation, and a series of functions that take a state object as input, and return a new modified state object.

    So let's create a hypothetical "state" value, that represents the state of a console screen. exactly how this value is constructed is not important, but let's say it's an array of byte length ascii characters that represents what is currently visible on the screen, and an array that represents the last line of input entered by the user, in pseudocode. We've defined some functions that take console state, modify it, and return a new console state.

    consolestate MyConsole = new consolestate;
    

    So to do console programming, but in a pure functional manner, you would need to nest a lot of function calls inside eachother.

    consolestate FinalConsole = print(input(print(myconsole, "Hello, what's your name?")),"hello, %inputbuffer%!");
    

    Programming in this way keeps the "pure" functional style, while forcing changes to the console to happen in a particular order. But, we'll probably want to do more than just a few operations at a time like in the above example. Nesting functions in that way will start to become ungainly. What we want, is code that does essentially the same thing as above, but is written a bit more like this:

    consolestate FinalConsole = myconsole:
                                print("Hello, what's your name?"):
                                input():
                                print("hello, %inputbuffer%!");
    

    This would indeed be a more convenient way to write it. How do we do that though?

    What is a monad?

    Once you have a type (such as consolestate) that you define along with a bunch of functions designed specifically to operate on that type, you can turn the whole package of these things into a "monad" by defining an operator like : (bind) that automatically feeds return values on its left, into function parameters on its right, and a lift operator that turns normal functions, into functions that work with that specific kind of bind operator.

    How is a monad implemented?

    See other answers, that seem quite free to jump into the details of that.

提交回复
热议问题