5 ms·
main = putStrLn "foo" Truly insane.
by aranchelk 3y ago
main = putStrLn "foo"
Truly insane.
- TylerE 3y agoCome on, that's not in good faith and you know it. That's a special case. Now do it inside a vanilla function that isn't implicitly run inside the IO monad.
- aranchelk 3y agoWhat do you mean by vanilla? A function that doesn’t have a monadic return value? What do you mean by run implicitly? I explicitly put IO expressions in the main function and they run. That’s the same as any imperative language. I’m trying to figure out what you’re getting at. Are you saying it’s hard to do IO outside of the IO Monad?
- tome 3y agoOne might say your original claim was not in good faith. You said > Look at all the monad insanity Haskell has to do to get the equivalent of a print statement but it's easy to do that! If you meant something more complex and subtle perhaps you should have made a more complex and subtle claim.
- TylerE 3y agoyea, it's so easy that's why there's dozens of many-page tutorials on the topic.
- Twisol 3y agoYou don't need to understand monads to do IO. From [0]: > There is nothing that has to do with monads at all in printing a string. The idea that `putStrLn "hello world"` is monadic is as absurd as saying that `[1,2,3]` is monadic. You haven't linked any exemplar tutorials, but I feel confident in saying the ones you're referring to teach the general concept of monads, and not how to do IO with monads. Quite a number of JavaScript developers learned how to use `andThen` with Promises/A+ back in the day, and they didn't need to learn about monads either. (In fact, when it was raised that promises are really monads, there was serious drama and outrage [1] -- an existence proof if there ever was one, that you can use something productively without understanding it as a monad.) Likewise, nobody would claim that you need to understand monoids before you can concatenate lists. Concatenating lists is as native to lists as sequencing commands is to IO; it's just part of how those types work. The monad interface abstracts over that idea, and learning that abstraction in its full generality is, typically, what people stumble on. [0]: https://blog.jle.im/entry/io-monad-considered-harmful.html https://blog.jle.im/entry/io-monad-considered-harmful.html [1]: https://github.com/promises-aplus/promises-spec/issues/94 https://github.com/promises-aplus/promises-spec/issues/94
- aranchelk 3y agoHow many articles are there on writing your first program in Python? Is that a result if it being difficult? This is not a valid method of assessment. Relative to programming in general, monads are easy to work with, easy enough to understand, but I’ll grant you often poorly explained.
- TylerE 3y agoArticles on python don’t generally start with “Ignore the thousands of other articles, this one ACTUALLY explains it”
- astrange 3y agoI think there was mostly a problem where people refused to stop trying to explain it with confusing burrito analogies. It's not too bad if you read the type definition and maybe read some compiler IL. (And of course "it's just a monoid in the category of endofunctors".)
- marcosdumay 3y agoYou seem to have made an uninformed opinion where you saw some people struggling to do one thing, and just assumed they were doing something completely different. Those people writing monad tutorials (those are written about as often as they are read) aren't trying to learn how to do I/O.
- coldtea 3y agoSo, like: myMethod :: IO () myMethod = putStrLn "Hello World!" Yes, so hard... "insane" /s
- TylerE 3y agoNow drop that in the middle of a larger function, outputing a value computed within that function.
- tome 3y agoAh, so now your original statement becomes clearer! When you said > Look at all the monad insanity Haskell has to do to get the equivalent of a print statement perhaps you really meant > Look at all the monad insanity Haskell has to do to get the equivalent of a print statement within pure code I still don't agree as such, but yes, there is indeed ceremony involved in turning something that was pure into something effectful. That is in fact the whole point!
- aranchelk 3y agoIn the IO monad: f x y z = do let foo = x + y bar = foo * z putStrLn $ "Here's bar" <> (show bar) pure bar If all you want is to log to the console for debugging from pure code, it would look like f x y z = let foo = x + y bar = foo * z in trace ("Here's bar" <> (show bar)) bar Not recommended, but if you're dead set on commingling your effectful and pure code, you can freely mix them with the function unsafePerformIO. In my experience having to write large applications with significant test coverage, the time savings from not screwing around with stubs and mocks and dealing with the external effects of test runs -- the relative annoyance of using a couple "do"s and "pure"s and separating out data transformation from IO is a small price to pay.
- quickthrower2 3y agoObviously extended to main = putStrLn “foo” >> putStrLn “bar”