# Please correct my use of Maybe Monad

I am implementing a small program that makes exponentiation ciphers. Some of the calculations can fail, for example, when calculating modular inversion. I've used Maybe to deal with similar setbacks. But now I am stuck as I need to "inject" the value inside, possibly into another partially applied function. I know that if I had a function that took one argument, I would use bind for that.

```
import Data.Char
import Math.NumberTheory.Powers
extendedGcd::Integer->Integer->(Integer, Integer)
extendedGcd a b | r == 0 = (0, 1)
| otherwise = (y, x - (y * d))
where
(d, r) = a `divMod` b
(x, y) = extendedGcd b r
modularInverse::Integer->Integer->Maybe Integer
modularInverse n b | relativelyPrime n b = Just . fst $ extGcd n b
| otherwise = Nothing
where
extGcd = extendedGcd
relativelyPrime::Integer->Integer->Bool
relativelyPrime m n | gcd m n == 1 = True
| otherwise = False
textToDigits::String->[Integer]
textToDigits p = map (\x->toInteger (ord x - 97)) p
digitsToText::[Integer]->String
digitsToText d = map (\x->chr ((fromIntegral x) + 97)) d
exptEncipher::Integer->Integer->Integer->Maybe Integer
exptEncipher m k p | relativelyPrime k (p - 1) = Just $ powerMod p k m
| otherwise = Nothing
exptDecipher::Integer->Integer->Integer->Integer
exptDecipher m q c = powerMod c q m
exptEncipherString::Integer->Integer->String->[Maybe Integer]
exptEncipherString m k p = map (exptEncipher m k) plaintext
where
plaintext = textToDigits p
exptDecipherString::Integer->Integer->[Maybe Integer]->Maybe String
exptDecipherString m k c = (fmap digitsToText) plaintext
where
q = modularInverse k (m - 1)
plaintext = map (fmap $ exptDecipher m q) c
```

Specifically, my problem is with the exptDecipherString function, where I needed to inject the monad-encapsulated value in q into the exptDecipher function, which I would then raise to work on c. What is the correct way to do this? Also, I'm worried that I end up with a [Maybe Char] list instead of the Maybe string I want. I am having problems explaining all of this. Can someone enlighten me?

source to share

You can use `sequence`

and `ap`

to get development types. First for their signatures:

`ap :: Monad m => m (a -> b) -> m a -> m b sequence :: Monad m => [m a] -> m [a]`

Please note what `sequence`

directs your concern about stock `[Maybe Char]`

instead `Maybe String`

. Both are in `Control.Monad`

(note that you will need to import `ap`

). We can use them like this:

```
exptDecipherString :: Integer -> Integer -> [Maybe Integer] -> Maybe String
exptDecipherString m k c = fmap digitsToText plaintext
where
q = modularInverse k (m - 1)
plaintext = sequence $ map (ap $ fmap (exptDecipher m) q) c
```

We can get to this by working through types. First we appy `exptDecipher`

up `m`

, which gives us a type function `Integer -> Integer -> Integer`

. We want to apply this to `q`

, but it's a `Maybe Integer`

, so we have to use `fmap (exptDecipher m) q`

that then has a type `Maybe (Integer -> Integer)`

. Then we can put `ap`

on the front and get something like `Maybe Integer -> Maybe Integer`

. Then we type this over `c`

, which gives us `[Maybe Integer]`

which we can turn inside out with `sequence`

.

It might not work - if there are bugs in the logic, etc., but at least it compiles.

A couple of notes: you can use infix `<$>`

and `<*>`

from operators `Control.Applicative`

instead of `fmap`

and `ap`

accordingly for a slightly stronger syntax, and yours `relativelyPrime`

can be written much easier than `relativelyPrime m n = gcd m n == 1`

.

source to share