1

I have the following code (using lookup from the Haskell Prelude):

al :: [(Char, Int)]
al = [("A", 1),
      ("B", 2),
      ("C", 3),
      ...
 ]

strToInt :: [Char] -> Int
strToInt []
 = 0
strToInt (c:cs)
 = lookup c al + strToInt cs

The problem is I am trying to perform addition on Maybe Int and Int which the compiler will not allow. How can I resolve this issue?

Adam Griffiths
  • 680
  • 6
  • 26
  • 60

3 Answers3

2

In this case, since you're adding values together, and it'd be natural to ignore Nothing values (i.e. treat them as 0), you could also write the function using mapMaybe:

import Data.Maybe (mapMaybe)

al :: [(Char, Int)]
al = [('A', 1), ('B', 2), ('C', 3)]

strToInt :: String -> Int
strToInt = sum . mapMaybe (`lookup` al)

GHCi:

*Q46515794> strToInt "AB"
3
*Q46515794> strToInt "AC"
4
*Q46515794> strToInt "ABC"
6
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
1

If the precondition is that the lookup will always be successful, use fromJust :: Maybe a -> a to parse the value - for example, fromJust (lookup c al).

Otherwise, you will need some 'default' value (e.g. 0) to return in case the lookup fails. Then you can use fromMaybe :: a -> Maybe a -> a which takes the default value as the first parameter and parses the value - for example, fromMaybe 0 (lookup c a1).

Anson Miu
  • 1,171
  • 7
  • 6
  • 3
    Those aren't the only two possibilities: they might want to propagate a `Nothing` with `(+) <$> lookup c a1 <*> strToInt cs`. – Davis Herring Oct 01 '17 at 19:38
1

I guess you have to have control on your logic. It is not known what you want when the character you provide returns Nothing, this function better return a Maybe type.

If you want to treat Nothings as 0 then mapMaybe is one way to go. Or if you want a Maybe type result then...

al :: [(Char, Int)]
al = [('A', 1), ('B', 2), ('C', 3), ('D', 4)]

strToInt :: [(Char, Int)] -> String -> Maybe Int
strToInt ts cs = foldr (\c m -> (+) <$> (lookup c ts) <*> m) (Just 0) cs

*Main> strToInt al "AJN"
Nothing
*Main> strToInt al "ABCD"
Just 10
Redu
  • 25,060
  • 6
  • 56
  • 76