Home > Software engineering >  how to return the literal 1 as Maybe Integer?
how to return the literal 1 as Maybe Integer?

Time:12-30

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 as Maybe 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)
  • Related