I am wondering if it is possible to wirte the Function
add :: Maybe Int -> Maybe Int
add Just x = Just (x+1)
add Nothing = Nothing
without the x
. Similar to
f = Just.(+1)
However
add Just = Just.(+1)
throws an error: Equations for 'add' have different numbers of arguments
.
Can someone please explain me why this does not work?
You need to pattern match somewhere - there's no way to "get the value out" without doing so. You can use some unsafe function, like fromJust
, but
The "proper modular" way to do this, would be to write this common pattern as a higher-order function, so that you can reuse it:
Nothing
case, you return Nothing
Just
case, you return Just
of some function applied to the arg insideTaking into account the two things above, we reach the following
maybeMap :: (a -> b) -> Maybe a -> Maybe b
maybeMap _ Nothing = Nothing
maybeMap f (Just x) = Just (f x)
which you can now use to write your desired function:
add :: Maybe Int -> Maybe Int
add x = maybeMap (+1) x
-- or we can eta reduce it - taking an argument and calling a function with it is the same as just returning the function directly
add = maybeMap (+1)
This function is traditionally called map, because you're mapping "the values inside a container" to something else.
This is something that you very often need to do for different "containers" (and some other kinds of things), so we have a type class for it in the standard library (base
), named after some theoretical things:
class Functor f where
fmap :: (a -> b) -> f a -> f b
instance Functor [] where
fmap = map
instance Functor Maybe where
fmap = maybeMap
Additionally, the error you're seeing is something else entirely. In Haskell, when writing a function definition, your different cases are not allowed to have different numbers of arguments taken:
-- not allowed, since in the first case you've taken two args,
-- but in the second you've only taken one.
bla :: Integer -> Integer -> Integer
bla 0 y = 42
bla x = id
-- this is fine, in both cases we have two arguments
bla :: Integer -> Integer -> Integer
bla 0 y = 42
bla x y = y