[a / b / c / d / e / f / g / gif / h / hr / k / m / o / p / r / s / t / u / v / vg / vm / vmg / vr / vrpg / vst / w / wg] [i / ic] [r9k / s4s / vip] [cm / hm / lgbt / y] [3 / aco / adv / an / bant / biz / cgl / ck / co / diy / fa / fit / gd / hc / his / int / jp / lit / mlp / mu / n / news / out / po / pol / pw / qst / sci / soc / sp / tg / toy / trv / tv / vp / vt / wsg / wsr / x / xs] [Settings] [Search] [Mobile] [Home]
Board
Settings Mobile Home
/g/ - Technology


Thread archived.
You cannot reply anymore.


[Advertise on 4chan]


File: 4o12.png (2 KB, 267x189)
2 KB
2 KB PNG
A monad is just a monoid in the category of endofunctors
>>
>>108447781
fr?
>>
File: file.png (42 KB, 757x237)
42 KB
42 KB PNG
this is the explanation for coombrain addicts like me
>>
>>108447834
a harem of harems is just a harem of all the people on each harem
it flattens compositional hierarchies into a flat group
>>
>>108447781
In Python we just call them "decorators".
>>
>>108447893
decorators are not (m a) -> (a -> m b) -> (m b). you could implement this in python pretty easily however.
>>
>>108447781
A monad occurs whenever you have functors between two categories (adjunction).
For example, the category of valid program output and the category of errors.
F: values -> errors
G: errors -> values
H: F G: values -> errors -> values
Composing those functors allows you to stay in values, but carry along the error state with you.
You're already using monads if you are checking for errors, like in Go with err != nil
Checking for an error is mapping from values to errors, then you map from errors back to values by choosing one of the program paths with the branch.
So you have F and G. You're just manually composing them into H, rather than having a language which supports automatically composing them, so that the boilerplate can be implicit.
>>
>>108448498
>You're already using monads if you are checking for errors, like in Go with err != nil
wrong. that is just error handling, that is not monadic.
>>
>>108448513
It is a monad. You're just manually defining the composition steps, rather than using a language construct which can automatically define those steps.
To give a more specific example, checking a value and then potentially outputting an error is literally Haskell's return (left identity monad law), just made more explicit.
The right identity is defined through branching on an error.
Composing those branches is the associativity law.
The only difference between error handling in Go and Haskell is that Haskell allows for the boilerplate to be generated by the compiler. In both cases, you're using monads.
>>
>>108448553
a monad would propagate the error, and handle the plumbing so to speak. this is done with the bind operator with the signature m a -> (a -> m b) -> m b. this is different that explicitly handling an error or even fmap, where the signature of (a -> b) -> m a -> m b. you have no idea what you are talking about.
>>
>>108448578
When Haskell compiles code down to assembly, it will turn an error handling monad into if else branches that are functionally identical to if err != nil in Go. The assembly is functionally the same in both cases, because they're both implementations of the Error monad. Haskell just makes this easy by directly abstracting the monad pattern.
The point I'm trying to make is that all error handling is already monadic, because you're mapping between two categories. Haskell simply abstracts out this pattern so that you don't have to write boilerplate.
>m a -> (a -> m b) -> m b
In Go, m a would be the program state from previous branching path taken. (a -> m b) is choosing a branch to take depending on if err != nil.
m b is the program state after choosing the branch
>(a -> b) -> m a -> m b
You're right that this is mapping a function onto a monadic value, but that's not the type signature for error handling.
This is mapping a function that does not return an error onto a value which may or may not be in an error state. That's different than composing values which may be errors with functions that might return errors.
>>
File: 1774283160641220.jpg (335 KB, 1259x1730)
335 KB
335 KB JPG
>>108447781
A monad is just a transform() followed by a join().
>>
>>108447918
They're effectively useless in Python.
>>
>>108447781
What's a dyad then?
>>
Monadeez nuts
>>
>>108448659
>The point I'm trying to make is that all error handling is already monadic
ok, here is an implementation of a maybe monad in the simplest language that does not have baked in support, notice when i use the monad i never handle the error? in fact i do not even have to think about errors, because that is what the bind function does for me. this is what monadic error handling is.

>Haskell simply abstracts out this pattern so that you don't have to write boilerplate.
if you are writing idiomatic haskell you are writing substantially different code than idiomatic go. i am not familiar with go, but i am use u can implement monadic operations with its compile time generics.
(define maybe-monad
(let ((the-nothing '(nothing))
(the-just '(just)))

(define (just v)
(list the-just v))

(define (just? v)
(and (pair? v) (eq? (car v) the-just)))

(define (nothing)
the-nothing)

(define (nothing? v)
(eq? the-nothing v))

(define (bind v f)
(if (nothing? v)
(nothing)
(f (cadr v))))

(lambda (m)
(case m
((just maybe) just)
((just?) just?)
((nothing) nothing)
((bind) bind)))))

(define (// x y)
(if (zero? y)
((maybe-monad 'nothing))
((maybe-monad 'just) (/ x y))))

(define (** x y)
((maybe-monad 'just) (* x y)))

(let ((maybe (maybe-monad 'maybe))
(bind (maybe-monad 'bind)))
(chain (maybe 20)
(bind _ (λ (x) (// x 10)))
(bind _ (λ (x) (** x 2)))
(bind _ (λ (x) (// x 0)))
(bind _ (λ (x) (** x 3)))
(bind _ (λ (x) (** x 12)))))
>>
>Haskell
use case?
>>
>>108449071
>i do not even have to think about errors, because that is what the bind function does for me
Precisely my point. Haskell (and functional languages in general) allow for abstracting out the boilerplate of a Monad into a generic function or similar concept.
In procedural languages, instead of being able to use a generic bind, the steps to bind have to be explicitly written out.
In both cases, you have a monad.
To refer back to the OP:
a monoid is a set with an associative binary operation and identity function
when that binary operation is an endofunctor (functor from a category back to itself), and identity lifts its input into the set/category, then now you have a monad
The identity function satisfies the type for return (a -> m a).
The endofunctor needs to satisfy m a -> (a -> m b) -> m b.
In procedural languages, you have to write out the steps for the endofunctor each time. In functional languages, you can make it generic function.
 
a, err = f1;
if err == nil {
b, err = f2;
if err == nil {
...
}
}

The above is merely the steps for monadic bind being written out explicitly.
In functional languages, you can abstract it into f1 >> f2.
Both cases are implementations of the abstract concept of an Error monad.
When Haskell compiles code down to assembly, you still have an error monad, but now the steps are written explicitly.
So when you use procedural languages, you're already using monads all the time. You just don't have a nice generic way of defining and composing them.
You could theoretically write a code generation frontend for a procedural language which can take in code like "f1 >> f2" and produce the above snippet. That code generation/syntactic sugar is not what makes the code monadic. What makes it monadic is the fact that the implementation satisfies the monad laws.
Whether any particular concept is written generically or explicitly doesn't change the fundamental concept which is being implemented.
>>
>>108449220
Moreover, consider how a dynamic array can be defined explicitly or generically.
You can either write out an explicit struct and set of functions for each type of dynamic array. Or you can write a generic template which will generate the code for a dynamic array given a particular type.
In both cases, you're defining an implementation of a dynamic array. It's just that in the second case, you've made it generic.
In exactly the same way, you can either write out each computation step of a monad explictly, or in functional languages, you can make it generic. In both cases, you're implementing a monad. It's just that in the second case, you've made it generic.
>>
>>108447781
i understood this shit at one point. discarded that info as soon as i accepted that haskell is useless
>>
>>108449220
>In procedural languages, instead of being able to use a generic bind, the steps to bind have to be explicitly written out.
in c++ i have written a monadic maybe class, that fully supports both fmap and bind. it is not a semantic or abstracting away boiler plating, i am writing fundamentally different code, that compiles to different assembly. this is fundamentally different than checking the return value or catching an exception. the definition of a monad is a type constructor that has the signature a -> m a, and a bind operation with the signature m a -> (a -> m b) -> m b. i am thankful you are probably not a lawyer.
>>
>>108449220
Monadic usefulness has nothing to do with procedural vs declarative. All languages, including Haskell, are procedural. The usefulness comes into play when a language is non-strict, because monads are a reification of ordering + context in a transparent way.

You aren't incorrect otherwise though. Especially hitting the mark with why it's hard for programmers using things like Python to understand them. They underestimate the primitive simplicity.
>>
>>108449277
>the definition of a monad is a type constructor that has the signature a -> m a, and a bind operation with the signature m a -> (a -> m b) -> m b
My point is that when you explictly write out error handling, you are literally writing out the implementation steps of these two functions. You have that exact same monadic behavior whether it's explicit or generic. You probably can make that behavior generic in c++ because it has templates and first class functions, but you're still implementing the same core pattern, which is the particular monad.
>>
>>108447918
python does not guarantee type discipline, so not even close
>>
>>108449346
refer to my implementation uses a language without static typing. you can implement this in python almost verbatim.
>>108449071
>>
>>108449401
that's not the point i am trying to make though, any program you write in python is not type safe, therefore any program that relies on the monad, or any program that the monad relies on will not be type safe, there's no point in reimplementing a monad if you can't guarantee this since a monad is supposed to operate as a pure function, whatever you did in python is not reliable in a mathematically pure sense
>>
>>108449457
Whatever you implement in any language gets turned into current running through holes in some rocks, so it will never be reliable in a mathematically pure sense.
>>
>>108449469
yes and that current burns an image through a phosphor screen that preserves type safety in haskell, therefore mathematically reliable, not python though, what you are doing is simulating monadic behaviour, not writing anything that can be described as a monad
>>
nigga i just wanna make a program that will automate shit for me in IT. why do i need to know what a monad is
>>
>>108449214
Category theory papers.
>>
File: Oof-size-large-meme-5.jpg (36 KB, 751x515)
36 KB
36 KB JPG
>>108449469
>static typing doesn't matter because the cpu runs untyped code
>>
>>108449904
Are you retarded?
>>
>>108449929
no. are you?
>>
>>108449938
You are. I'm not.
>>
>>108449516
it helps you write more pure functions in the rest of your program, which will make it easier to reason about. Making changes later to the script will probrably be easier
>>
>>108449214
Flexing on normies.
>>
>>108449484
>what you are doing is simulating monadic behaviour
are you brain damaged? "simulating"? its a formula that defines what it is, you can implement a monad in any language. is there something about ocamls compiler that makes the formula behave differently than haskells or pythons interpreter. everything is more or less a "simulation".
>>
>>108450014
again, there are side effects in non static compilers, the functions you are using to implement the monad are not pure functions, none of the dependencies or libraries in python used for this can be said to be pure, you'd see what i mean if you weren't half retarded
>>
>>108449516
>why do i need to know what a monad is
You don't, but you probably already used it with shit like the Option/Maybe type, the Builder pattern, LINQ, ReactiveX, etc.
Being able to tell that they all do basically the same thing and also knowing the name of that thing helps you identify where similar patterns may be applicable, which makes you a better software engineer, imo.
And also allows you to do this >>108449997
>>
>>108450031
Nothing can ever be pure, retard. The purity exists only in your head. Saying that a definition of a monad written in python is any different from the same definition written on a piece of paper is either peak stupidity or a bad attempt at trolling. Unless there is a mysterious purity force smiting you over smallest mistakes while using a pen.
>>
>>108450044
you are functionally retarded and don't understand type theory or why python is different from haskell, and there's no definition written, we are writing implementations of a monad, functions that take inputs and produce outputs
>>
>>108447781
I never understood functional masturbation, nigga what are talking about? It's just a bunch of bytes, and a programming system (a language) should just produce the ISA understood by the processor.
>>
>>108450074
you really have no idea what you are talking about. define your understanding of type theory, and explain why the type implementation matters to the degree you are claiming, where somehow a -> ma and m a -> (a -> m b) -> mb is not preserved with dynamic typing.
>>
>>108450074
Please tell me you are just trolling.
>>
>>108450081
If you think of languages as what they can compute, all languages are Turing complete so the same. The other view is how you reason about what you write. Lets say youre writing a Linux driver in C. You write a function that uses a flag, which is a shared state. To accurately reason about your function, you have to reason about what all other functions that write to the flag do, and what you will do to them if you write to it. In an FP, you only have to reason about what is locally given to you in your input. So its partially ideological, partially practical.
>>
>>108450129
how about this, write that definition of a monad, which you have written in haskell notation, in python notation, better yet, what does a, ma,mb and b mean in python, are they types you can implement in python, random memory locations, can you trace their type dependency?
>>
File: hegel chad.jpg (16 KB, 199x253)
16 KB
16 KB JPG
>>108447781
Monad is bae
>>
>>108450129
what does -> and () mean in python, does python have fixity
>>
>>108450185
all that 'm a' has to be is 'a' with additional information. bind is 'm a -> (a -> m b) -> m b' means a function that takes 'type a with information about state' and 'function that takes type a and returns type m f(a)' and return 'type b'. that is all it is.
>are they types you can implement in python, random memory locations, can you trace their type dependency
do u think that python does not have types? when you create a class that is in fact a new type. i literally wrote an implementation in scheme where i never even create a new type.
>>108449071
>>
>>108450220
im sleepy i meant to say
'function that takes type a and returns type f(a) with information about state' and return 'type b with information about state'.
>>
>>108449457
>there's no point in reimplementing a monad if you can't guarantee this since a monad is supposed to operate as a pure function
The point of Monads is to get rid of boilerplate. That's all. The purity is just part of how haskell works.
Suppose you have a list monad in haskell. As all functions are pure, the monad never modifies the list in place, it always returns a new one.
Suppose it instead modified the list in place. Is it no longer a monad? The monad laws are still satisfied. So why would the impurity prevent it from being a monad? You can still use it to hide boilerplate. As in the OP, a monad is just a monoid in the category of endofunctors. Notice how none of that is required to be pure.



[Advertise on 4chan]

Delete Post: [File Only] Style:
[Disable Mobile View / Use Desktop Site]

[Enable Mobile View / Use Mobile Site]

All trademarks and copyrights on this page are owned by their respective parties. Images uploaded are the responsibility of the Poster. Comments are owned by the Poster.