Reputation: 493
I can multiply a list per 2:
(* 2) <$> [1, 2, 3]
But I want multiply the elements which are Just:
(* 2) <$> [Just 1, Nothing, Just 3]
Error:
* Non type-variable argument in the constraint: Num (Maybe a) (Use FlexibleContexts to permit this) * When checking the inferred type it :: forall a. (Num (Maybe a), Num a) => [Maybe a] Prelude Data.List
Another try:
fmap (* 2) [Just 1, Nothing, Just 3]
Error:
* Non type-variable argument in the constraint: Num (Maybe a) (Use FlexibleContexts to permit this) * When checking the inferred type it :: forall a. (Num (Maybe a), Num a) => [Maybe a]
I have tried more things: map2, fmap2, map (*2) map, etc.
Upvotes: 2
Views: 1976
Reputation: 9294
You can compose 2 fmap
functions:
(fmap . fmap) (*2) [Just 1, Nothing, Just 3]
The first will be the fmap of the list, the second is the fmap of the maybe.
Upvotes: 2
Reputation: 80915
You need to map twice: once to get inside the list, second time to get inside the maybe. The operator <$>
only maps once, and you can't use the same operator twice, so you have to add a call to fmap
:
fmap (* 2) <$> [Just 1, Nothing, Just 3]
Upvotes: 7
Reputation: 34398
A straightforward solution is adding another fmap
to get through the Maybe
layer:
GHCi> fmap (* 2) <$> [Just 1, Nothing, Just 3]
[Just 2,Nothing,Just 6]
Alternatively, that can be expressed using Compose
, which allows handling the two functor layers as one:
GHCi> import Data.Functor.Compose
GHCi> (* 2) <$> Compose [Just 1, Nothing, Just 3]
Compose [Just 2,Nothing,Just 6]
GHCi> getCompose $ (* 2) <$> Compose [Just 1, Nothing, Just 3]
[Just 2,Nothing,Just 6]
Upvotes: 10