4 May 2024 |
dxtr | Oh | 19:45:57 |
dxtr | <|> is literally what I wanted | 19:46:05 |
Bowuigi | In reply to @alex:tunstall.xyz
The most obvious similarity it has to boolean AND is that both are monoids (see All and Alt in Data.Monoid ).
This isn't saying much, because monoids show up all over the place when you go out of your way to look for them.
By the way, Alternative IO doesn't match your description of what you want.
If you look at the documentation, it says "Takes the first non-throwing IO action's result."
The code return (Left "hello") does not throw, so (<|>) will use it instead of trying the next argument.
You cannot use (<*>) or liftA2 to do what you want because that will always run the second IO action. More generally, one consequence of the Applicative laws is that the functorial structure (or side effects) of the result cannot depend on the contents of the arguments.
To do that, you need Monad , which allows such conditional "side effects" through (>>=) . Note that (>>=) :: m a -> (a -> m b) -> m b ; the m b argument is allowed to depend on a , unlike in (<*>) :: m (a -> b) -> m a -> m b and liftA2 :: (a -> b -> c) -> m a -> m b -> m c .
You'll find that _1 >>= either _2 return is what you're looking for, where _1 and _2 are your IO (Either a b) actions. You could bind this to a custom operator, e.g. a >>| b = a >>= either b return . That is the same problem as this but with other monad | 19:46:21 |
dxtr | I think it's the first time I actually found the function I wanted by looking at the function signature | 19:46:26 |
dxtr | Hmm, no that didn't seem to work | 19:52:22 |
@21it:matrix.org | In reply to @kjlid:matrix.org How would I chain a bunch of IO (Maybe a) , stopping on the first Just ? Welcome to the world of monad transformers! https://hackage.haskell.org/package/transformers-0.6.1.1/docs/Control-Monad-Trans-Maybe.html#t:MaybeT | 20:24:04 |
@21it:matrix.org | So <|> is correct answer, but for MaybeT IO a instead of IO (Maybe a) | 20:24:57 |
dxtr | Yeah MaybeT was the first thing I reached for and then I thought "I bet there's an easier way" | 20:25:27 |
dxtr | * Yeah MaybeT was the first thing I reached for and then I thought "I bet there's a simpler way" | 20:25:52 |
dxtr | Oh, monads.. Why do you have to do me dirty like this? | 20:27:41 |
@21it:matrix.org | I also don't like monad transformers on top of IO-like monad for specific control flow. I think ReaderT is the only transformer which is allowed in my programs | 20:30:34 |
Jade | of course you can also write this by hand | 20:30:45 |
@21it:matrix.org | of just have exceptions for early return, in your example you already in IO anyways π | 20:31:44 |
@21it:matrix.org | But MaybeT m a is not that bad as ExceptT e m a , because there is no e parameter on your way, composes way better | 20:36:38 |
dxtr | Anyone here using the repl in haskell-mode in emacs? Can I 'eval' the current buffer in it? | 20:50:24 |
dxtr | Oh there we go, C-c C-l | 20:51:20 |
Bowuigi | In reply to @kjlid:matrix.org How would I chain a bunch of IO (Maybe a) , stopping on the first Just ? _1 >>= maybe _2 return is the solution mentioned last time, but adapted to maybe | 22:14:54 |
Bowuigi | Adapting this to work on an arbitrary data structure should be easy enough, but just using this as a function is probably what you want | 22:16:06 |
| vlnovl joined the room. | 22:17:10 |
Bowuigi | The operator is right associative btw, otherwise you get the wrong types | 22:19:24 |
tzlil | Redacted or Malformed Event | 22:33:48 |
tzlil | Redacted or Malformed Event | 22:35:11 |
5 May 2024 |
MangoIV | MaybeT is such a useful monad transformer. Probably by far the one I use the most. | 07:39:54 |
clementd-42 | I think Compose works as well, but sometimes using a monad transformer is more convenient even when not strictly needed. | 07:46:02 |
clementd-42 | * I think Compose works as well here, but sometimes using a monad transformer is more convenient even when not strictly needed. | 07:59:05 |
clementd-42 | (otoh, the beauty of traverse Compose is hard to overstate) | 07:59:45 |
| πππΌπ»πΊπ
π
changed their display name from nicball : to πππΌπ»πΊπ
π
. | 08:55:39 |
Alex | In reply to @clementd-42:matrix.org I think Compose works as well here, but sometimes using a monad transformer is more convenient even when not strictly needed. Compose IO Maybe doesn't work, because it uses Alternative IO . See the instance's constraints. | 11:55:44 |
comonadic | I didn't find anything on lawvere theory in Haskell that proposes a method to encode monads in a way they are easily composable | 11:59:04 |
Alex | comonadic have you looked into adjunctions?
IIUC any monad can be encoded as an adjunction between two functors and via this encoding the monads can be composed, though I've yet to hear of a general construction for adjoint functors given any monad. It seems unlikely to be possible using only endofunctors. | 16:18:55 |