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
1
asMaybe 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)