8 ms·
But is writing such functions, and all the auxiliaries, pleasant as well? What type would I have to give the "getData" function to work in all these examples? W
by tom_mellior 9y ago
But is writing such functions, and all the auxiliaries, pleasant as well? What type would I have to give the "getData" function to work in all these examples? What if I just want to call an existing getData function that returns a Maybe, not some generic monad thing? Would I have to tweak the syntax for all the different monads I want to call it from?
Also, what would the print call really look like in actual code? This post talks about composing IO with other monads. I've never seen a monad composition example that wasn't peppered with calls to unintuitively named functions like liftM_.
The pseudocode looks nice, but if the pseudocode isn't a faithful representation of actual use, then it's not very useful.
- mabbo 9y agoYou don't necessarily need to implement each function perfectly generically. You maybe could, but that's not the point here. The benefit, as I see it, is that the main method doing all of these things is clear in its purpose regardless of which monad is being used. It's moving code more towards "this is what I want" rather than "here's how to do what I want".
- ves 9y agoWe have a library called `mtl` that addresses both abstracting over specific monads in order to achieve polymorphism and do all the `lift`ing ahead of time. You should find some reading material on it, it’s really quite a nice solution! I’m on mobile, otherwise this would’ve been an answer instead of a comment.
- dllthomas 9y agoWriting abstract functions is usually easier than writing concrete functions, because there are fewer ways things can fit together that look anything like correct. (Abstract in this way, in this kind of context...)
- Munksgaard 9y agoMaybe is already a monad.
- dllthomas 9y agoAs I read it, the question was "I have `... -> Maybe a` and I want to use it in a context where I am chaining together some unspecified monad. Will that be awkward?" And the monad interface doesn't help us with that. But the answer is that you have a Maybe, you can do any Maybe thing with it.
- tom_mellior 9y agoYes. That would allow me to use a getData returning a Maybe in the Maybe monad. But I wouldn't be able to use it in the list monad, or the others mentioned in the article.
- dllthomas 9y agoYou could use it in code that's operating in the list monad, you just wouldn't be able to stitch the computation in using the monad interface. But you could run it and get a Maybe back, and look at the Maybe, and turn it into something you can stitch in. `maybe (fail "got back a Nothing") pure` is probably the most generic way, but it may or may not be what you want.
- marcosdumay 9y agoWell, yes. You will need to convert your type into something else to use in another monad. As an example, it's common to track failure with an `Either Text` monad, but functions that can fail on a single way usually have an `Maybe a` return type. That means you will probably have an `Text -> Maybe a -> Either Text a` function around and write code like this: toEither "Error message" $ functionInMaybe a b
- leshow 9y agoYou could use the getData function just fine from anywhere. It's just that you wouldn't be able to use both the list monad instance and the maybe monad instance at the same time without a library like mtl.
- leshow 9y ago> What if I just want to call an existing getData function that returns a Maybe, not some generic monad thing? Maybe is a Monad. In Haskell, Monad is sort of like an interface (called typeclass) that a bunch of types implement. Maybe has an instance of Monad already, same with lists, and continuations, etc.
- chousuke 9y agoThe most common way you generate such generic functions is by using higher order functions like fmap etc, not by directly coding them using do notation, though it is nice to have when you do need it. In languages that have no access to the monad abstraction you'll still need a way to replace your database access with something that you can use during your testing. A monadic database interface won't save you from having to check that your application doesn't do silly things with the database as a side-effect, but it will make it much easier to test that your actual data processing is correct.