My question relates to the answer to another question: https://stackoverflow.com/a/11766789/3212958
In his answer, ertes writes the following type signature
select :: [a] -> [(a, [a])]
However, when select is actually used, ertes writes the following inside of a do block
(y, ys) <- select xs
Please help me shed some light on how the tuple (y, ys) matches the return type of select, namely [(a, [a])]. Is Haskell coercing the types at some point? (Does Haskell ever coerce types?) Is <- extracting a tuple of type (a, [a]) from the list monad that select returns?
Thanks, Max
--- EDIT: ---
@Lee reminds newbs to desugar before trying to reason about types. After making >>= explicit, it's more clear what's going on. After desugaring, the function in question looks like:
select xs >>= \(y, ys) -> fmap (y:) (perms (n - 1) ys)
And for lists, xs >>= f = concat (map f xs). So a better reading of (y, ys) in this context is as the signature of the function to map over the list.
selectreturns a list. If you writea <- select xsthenais every element ofselect xs. If you later writefunc a, the result of that is the result of applyingfuncto every element ofselect xs. This is just how the list monad is defined.a <- select xs; func ais the same asselect xs >>= func. Bind for lists is defined as :m >>= f = concat (map f m), so you are writingmap func (select xs). There is no type coercion in haskell. - user2407038ais not 'every element',arepresents one (arbitrary but specific) element of the list. - Justin L.