Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When running 'sequence' on a list of Eithers, how does ghc know which argument to list-ify?

Tags:

haskell

ghc

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:

  1. 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?

  2. 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

like image 205
craigbot Avatar asked Jun 28 '21 14:06

craigbot


1 Answers

  1. 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".

  2. 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.

like image 179
Noughtmare Avatar answered Oct 26 '22 22:10

Noughtmare