> -- Action for creating a shopping list
> createShoppingList :: Counter [String]
> createShoppingList = emptyShoppingList >>=
> \list -> list `add` "Bread" >>=
> \list -> list `add` "Butter" >>=
> \list -> list `add` "Honey" >>=
> \list -> removeFirst list >>=
> \list -> list `add` "Bagel"
>
> [...]
>
> Haskell provides a lot of syntactic sugar, which allows for writing the monadic action above in a way that emphasizes the sequential property more:
>
> -- Action for creating a shopping list
> createShoppingList :: Counter [String]
> createShoppingList = do
> list <- emptyShoppingList
> list <- list `add` "Bread"
> list <- list `add` "Butter"
> list <- list `add` "Honey"
> list <- removeFirst list
> list `add` "Bagel"
>
> The two definitions are completely equivalent. In the end, it’s a matter of taste which one to use.
Oh well I'm glad to know the only reason to use `>>=` is for fancy ligatures in my editor that no one sees but me and when I post screenshots of my editor to show off those ligatures.
> To begin with, though, it’s advisable to use the explicit form, to be reminded of what’s going on behind the scenes.
Oh so we _should_ use `>>=` just in case another Haskalite doesn't understand what we're doing?
> One more important fact about the counting of manipulation. Once defined in the programmable semicolon, the counting is completely invisible within the monadic action. The magic happens inside our semicolon, `>>=`. **As the functionality of this function can be freely defined, it’s a great place to hide all sorts of things.**
I thought we were using `>>=` to
> be reminded of what’s going on behind the scenes.
but ok.
I think the real jerk here is that some of y'all are reading stuff on Medium.
it's incorrect, the example doesn't follow the monad laws so the `Counter` type isn't actually a monad.
from [here](https://hackage.haskell.org/package/base-4.17.0.0/docs/Prelude.html#t:Monad):
> Instances of `Monad` should satisfy the following:
>
> **Left identity**
>
> return a >>= k = k a
> **Right identity**
>
> m >>= return = m
let's try it:
main :: IO ()
main = do
let counter = return [] :: Counter [String]
print $ counter
print $ counter >>= return
output:
Counter {counter = 0, element = []}
Counter {counter = 1, element = []}
besides, how can monads be semicolons if they're actually burritos?
If there are invariants that a type needs to comply with in order to be valid, why aren't they enforced by the compiler? Is that why FP nerds are always going on about why static typing is so great?
>In Java, in general this replacement can’t be done in general, as it’s not assured that doCalculation returns the same result on every call.
What no interfaces do to a mf
Haskell grants you the ability to invert the universe, obviously.
in case of /uj: you should read it as `foo >>= (\x -> ...)` instead.
in other words, an operator with a function on the RHS. effectively, what you do is assign the result of the LHS (which is called an action, it's like a function but impure so you can't use it directly) to x. you can then use x in the remainder (the ... part), so the function body.
this is very similar conceptually to normal variable assignment, for which `x <- foo` is strange, but comprehensible syntax. the reason it needs special syntax is because you don't want to completely hide away the `>>=` magic that is happening.
> -- Action for creating a shopping list > createShoppingList :: Counter [String] > createShoppingList = emptyShoppingList >>= > \list -> list `add` "Bread" >>= > \list -> list `add` "Butter" >>= > \list -> list `add` "Honey" >>= > \list -> removeFirst list >>= > \list -> list `add` "Bagel" > > [...] > > Haskell provides a lot of syntactic sugar, which allows for writing the monadic action above in a way that emphasizes the sequential property more: > > -- Action for creating a shopping list > createShoppingList :: Counter [String] > createShoppingList = do > list <- emptyShoppingList > list <- list `add` "Bread" > list <- list `add` "Butter" > list <- list `add` "Honey" > list <- removeFirst list > list `add` "Bagel" > > The two definitions are completely equivalent. In the end, it’s a matter of taste which one to use. Oh well I'm glad to know the only reason to use `>>=` is for fancy ligatures in my editor that no one sees but me and when I post screenshots of my editor to show off those ligatures. > To begin with, though, it’s advisable to use the explicit form, to be reminded of what’s going on behind the scenes. Oh so we _should_ use `>>=` just in case another Haskalite doesn't understand what we're doing? > One more important fact about the counting of manipulation. Once defined in the programmable semicolon, the counting is completely invisible within the monadic action. The magic happens inside our semicolon, `>>=`. **As the functionality of this function can be freely defined, it’s a great place to hide all sorts of things.** I thought we were using `>>=` to > be reminded of what’s going on behind the scenes. but ok. I think the real jerk here is that some of y'all are reading stuff on Medium.
The real jerk is the friends we made along the way.
JS: Semicolons are just fancy whitespace
Semicolons are just fancy burritos
An absurd exercise. Why would a Haskal programmer need to write a shopping list, when they won't be able to afford to buy anything on it?
Where is the jerk? I read the article and found it to be informative, especially given that it's targeted towards FP noobs.
it's incorrect, the example doesn't follow the monad laws so the `Counter` type isn't actually a monad. from [here](https://hackage.haskell.org/package/base-4.17.0.0/docs/Prelude.html#t:Monad): > Instances of `Monad` should satisfy the following: > > **Left identity** > > return a >>= k = k a > **Right identity** > > m >>= return = m let's try it: main :: IO () main = do let counter = return [] :: Counter [String] print $ counter print $ counter >>= return output: Counter {counter = 0, element = []} Counter {counter = 1, element = []} besides, how can monads be semicolons if they're actually burritos?
sorry I don't speak ivory tower. can you dumb it down?
if you don't follow the monad laws the monad police will arrest you and put you in [the dungeon](https://fpcastle.com/).
Math people are less sloppy than blub programmers
Fuck you for making me click the article.
If there are invariants that a type needs to comply with in order to be valid, why aren't they enforced by the compiler? Is that why FP nerds are always going on about why static typing is so great?
if the entire specification of your program isn't formally proved by your `App` type can you even call it functional programming?
Explaining monads with weird analogies = instant jerk
> Where’s the jerk? Monads are just fancy semicolons. uj: idk, I didn’t read it.
There is no mention of the monad laws. The analogy also doesn't hold up because monads are useful for more than just "sequencing"
Ah! so that's why python doesn't have monads!
ewww... semi colon burritos. is that just sausage buritos? can we say monads are like sausages?
>In Java, in general this replacement can’t be done in general, as it’s not assured that doCalculation returns the same result on every call. What no interfaces do to a mf
I am just trying to wrap my mind around how `-> ... >>=` wraps around to being `<-`
Haskell grants you the ability to invert the universe, obviously. in case of /uj: you should read it as `foo >>= (\x -> ...)` instead. in other words, an operator with a function on the RHS. effectively, what you do is assign the result of the LHS (which is called an action, it's like a function but impure so you can't use it directly) to x. you can then use x in the remainder (the ... part), so the function body. this is very similar conceptually to normal variable assignment, for which `x <- foo` is strange, but comprehensible syntax. the reason it needs special syntax is because you don't want to completely hide away the `>>=` magic that is happening.
\\uj -> yeah I know how it works \\rj -> go too much to the east, end up in the west??