I have two functions, and I'm confused about how the sequence knows which argument to put into a list, and what actually happens with the Lefts in the Either
getMonStat :: T.Text -> IO (Either CmdError MonStat)
..
getMonStats :: [T.Text] -> IO (Either CmdError [MonStat])
getMonStats ms = do
monStats <- mapM getMonStat ms
pure $ sequence monStats
My questions are:
Why does this work? After the mapM, I have monStats :: [Either CmdError MonStat]
. Running sequence on [m a]
turns it into m [a]
. Why isn't the initial type [m a b]
since CmdError
is a type as well? And if CmdError
is a type to consider, how does ghc know to pick MonStat
instead of CmdError
to list-ify? Or with types: why does sequence convert to m a b -> m a [b]
instead of m a b -> m [a] b
?
Which Left from [Either CmdError MonStat]
would the final CmdError
in Either CmdError [MonStat]
be? The first? A concated string of all of them? I could test but I'm curious in the why as well.
Thank you for any insights into this
Type applications are curried too, and they associate to the left: [m a b] = [(m a) b] = [m' b]
where m' = m a
. So it always takes the last argument to "list-ify".
It takes the first Left
in the list. That is the way the Monad
instance for Either
is defined: Left x >>= _ = Left x
. The sequence
function uses that Monad
instance. See this question about collecting all failures.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With