Reputation: 5086
I have a Haskell code that has two functions:
The first function:
functionA :: [Int] -> Maybe Int
The second one:
functionB :: Int -> Maybe Int
What I want to do is to recurse on every element of [Int] and feed it into functionB. If function B returns an Int, then move to the next element, if it returns Nothing, then functionA returns nothing too.
Any idea how best to do this?
Thanks :)
Upvotes: 1
Views: 566
Reputation: 1803
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
Upvotes: 0
Reputation: 33637
Your question has few things that are not clear hence I am making few assumptions.
functionA
is like a fold as it transform a [Int]
to Maybe Int
but before folding the ints it calls functionB
to transform each integer into a Maybe Int
where Nothing
result indicate a failure in transformation and which leads to failure of the functionA
and making it return Nothing
.
import Control.Applicative
functionA :: [Int] -> Maybe Int
functionA nums = foldl (\x y -> (+) <$> x <*> y) (Just 0) $ map functionB nums
functionB :: Int -> Maybe Int
functionB 2 = Nothing
functionB x = Just (x+x)
In the example above, the +
is used in the fold operation and functionB
fails on number 2
Upvotes: 1
Reputation: 74354
You can use sequence
to take [Maybe Int]
to Maybe [Int]
functionA ints = sequence (map functionB ints)
Generally this combination of sequence
and map
is called mapM
.
functionA ints = mapM functionB ints
Upvotes: 3