I am learning Haskell and having trouble returning literal 1 as Maybe Integer
alwaysOne:: Integer -> Maybe Integer
alwaysOne n = 1
raises
error:
• No instance for (Num (Maybe Integer))
arising from the literal ‘1’
• In the expression: 1
In an equation for ‘alwaysOne’: alwaysOne n = 1
|
14 | alwaysOne n = 1
| ^
CodePudding user response:
having trouble returning literal
1asMaybe Integer
The Maybe a type has two data constructors:
data Maybe a = Nothing | Just a
You need to use one of these data constructors if you want to produce a Maybe Integer value. What you want is to pass the 1 to the Just data constructor:
alwaysOne:: Integer -> Maybe Integer
alwaysOne n = Just 1
That is, Just takes a value of any type and produces a value of Maybe parametrized for that type:
Just :: a -> Maybe a
a above is inferred as Integer in your case.
Analogously, if you wanted to define alwaysNothing:
alwaysNothing :: Integer -> Maybe Integer
alwaysNothing _ = Nothing
CodePudding user response:
You could, technically speaking, make Maybe a an instance of Num if a is an instance of Num. But you should not do that.
Technically, it is possible with:
import Control.Applicative(liftA2)
instance Num a => Num (Maybe a) where
(*) = liftA2 (*)
( ) = liftA2 ( )
abs = fmap abs
signum = fmap signum
negate = fmap negate
fromInteger = pure . fromInteger
This then also allows to write Just 2 * Just 4 (for Just 8) for example, and then you can use 42 to return Just 42.
That being said, it would probably only add a lot of confusion. Therefore you just might use:
alwaysOne :: Num b => a -> Maybe b
alwaysOne = const (Just 1)
