J. Abrahamson answered right, but he named the result function unusually and it confused you.
Let we have ints:
ints :: [a]
functionA :: [a] -> Maybe a
functionB :: a -> Maybe a
So we wish to get map functionB
:
functionC :: a -> Maybe [a]
functionC ints = mapM functionB ints
but functionC
has result type Maybe [a]
, not [a]
, so we use fmap
result :: [a] -> Maybe a
result ints = join $ fmap functionA $ functionC ints
And we also use join
to get rid of Maybe (Maybe a)
result
Or let's write in one line:
result :: [a] -> Maybe a
result = join . fmap functionA . mapM functionB
UPDATED
But in this solution always calculates all ints
.
If we wish to stop calculating, we need to have mapIfAllJust
function, like this:
result :: [a] -> Maybe a
result = join . fmap functionA . sequence . mapIfAllJust functionB
mapIfAllJust :: (a -> Maybe b) -> [a] -> [Maybe b]
mapIfAllJust _ [] = []
mapIfAllJust f (x:xs) = go f (f x) [] xs
where
go _ Nothing _ _ = [Nothing]
go _ pr used [] = pr : used
go f pr used (nxt:rst) = go f (f nxt) (pr : used) rst
functionA
by usingfunctionB
? What happens if more than one of theInt
s gives anInt
instead ofNothing
? Just return the first one that worked, or return a list of all of the ones that worked? – not my job