Haskell - How to use a function that returns "Maybe Int" as an argument to another function?

When I have two functions:

and)

three :: Int -> Maybe Int
three a
 | a == 3 = Just 3
 | otherwise = Nothing

      

b)

takeOne :: Int -> Int
takeOne a = (a - 1)

      

how do I call function a as a parameter to function b? ie How do I let function b accept "Maybe Int" instead of "Int"?

The moment I try

takeOne (three 3)

      

I am getting the error:

ERROR - Type error in application
*** Expression     : takeThree (three 3)
*** Term           : three 3
*** Type           : Maybe Int
*** Does not match : Int

      

Thank.

+3


source to share


2 answers


You have several options, but I would say that the simplest is fmap

:

fmap :: Functor f => (a -> b) -> f a -> f b

      

Example:

> fmap takeOne $ three 3
Just 2
> fmap takeOne $ three 2
Nothing

      

Another option would be to use a function maybe

that takes a default, a function that is applied to whatever value inside Just

, and then to Maybe a

apply that parameter. An example should make it clear

> maybe 0 takeOne $ three 3
2
> maybe 0 takeOne $ three 2
0

      

Another alternative, if you just want to provide a default value, is to use a function fromMaybe

from Data.Maybe

:

> import Data.Maybe
> fromMaybe 0 $ three 3
3
> fromMaybe 0 $ three 2
0

      




In Haskell, there is a class called Functor

, defined as

class Functor f where
    fmap :: (a -> b) -> f a -> f b

      

There are many different types that are instances Functor

. In fact, all parameterized data structure Functor

s, as well as all Applicative

and Monad

s. The lightest mental model Functor

is that this is just a fancy name for a container. For example, for lists fmap = map

. All it does is render the function over the elements inside the container.

Some more examples:

> fmap (+1) (Left "error")
Left "error"
> fmap (+1) (Right 1)
Right 2

> x <- fmap (++", world") getLine
Hello
> x
Hello, world

> fmap (+1) [1..5]
[2,3,4,5,6]

> fmap (+1) ("fst", 2)
("fst", 3)

      

Even functions Functor

s! Here fmap = (.)

, this is just the normal composition of the function:

> let lengthPlusOne = fmap (+1) length
> lengthPlusOne "Hello"
6

      

+14


source


Another option, of course, is to write your own.

data IAcceptedAMaybeInt = GotAnswer Int | NothingAtTheMoment deriving Show

pleaseAcceptAMaybeInt f g a = case g a of
                                Just b    -> GotAnswer (f b)
                                otherwise -> NothingAtTheMoment

      



Output:

*Main> pleaseAcceptAMaybeInt takeOne three 3
GotAnswer 2

*Main> pleaseAcceptAMaybeInt takeOne three 2
NothingAtTheMoment

      

0


source







All Articles