MRE:
foo :: (Eq a) => a -> [a] -> Maybe Int
foo _ [] = Nothing
foo n (m:ms)
| -- some conditional statements that return Just <number here>
| otherwise = 3 + (foo n ms)
Error:
Could not deduce (Num (Maybe Int)) arising from a use of ‘+’
from the context: Eq a
bound by the type signature for:
foo :: forall a. Eq a => a -> [a] -> Maybe Int
at functions.hs:22:1-40
In the expression: 3 + (foo n ms)
What works:
otherwise = fmap (+3) (foo n ms)
Is there any way to do this without fmap?
PS: The only constraint on a is Eq has to hold.
The problem is that 3 is Int but (foo n ms) is Maybe Int, and you cannot add them.
You can pattern match on the result of foo n ms explicitly if you don't want to fmap over Maybe Int.
otherwise = case foo n ms of
Just x -> Just (3 + x)
Nothing -> Nothing
It's also an option to use a Monad instance of Maybe, but it's kind of a redundant version of fmap (+3) (foo n ms).
otherwise = do
x <- foo n ms
pure (3 + x)
Yet another option would be lifting (+) to Maybe Int -> Maybe Int -> Maybe Int with liftA2, but again, it's kind of another redundant version.
otherwise = liftA2 (+) (Just 3) (foo n ms)