I'm currently in the process of trying to learn Haskell, and ran into an odd issue regarding the Maybe
monad which I can't seem to figure out.
As an experiment, I'm currently trying to take a string, convert each letter to an arbitrary number, and multiply/combine them together. Here's what I have so far:
lookupTable :: [(Char, Int)]
lookupTable = [('A', 1), ('B', 4), ('C', -6)]
strToInts :: String -> [Maybe Int]
strToInts = map lookupChar
where
lookupChar :: Char -> Maybe Int
lookupChar c = lookup c lookupTable
-- Currently fails
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
test seq = [ x * y | (x, y) <- zip seq $ tail seq, x < y ]
main :: IO ()
main = do
putStrLn $ show $ test $ strToInts "ABC"
When I try running this, it returns the following error:
test.hs:13:16:
Could not deduce (Num (Maybe n)) arising from a use of `*'
from the context (Num n, Ord n)
bound by the type signature for
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
at test.hs:12:9-48
Possible fix: add an instance declaration for (Num (Maybe n))
In the expression: x * y
In the expression: [x * y | (x, y) <- zip seq $ tail seq]
In an equation for `test':
test seq = [x * y | (x, y) <- zip seq $ tail seq]
I'm not 100% sure why this error is occurring, or what it exactly means, though I suspect it might be because I'm trying to multiply two Maybe
monads together -- if I change the definition of test
to the following, the program compiles and runs fine:
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
test seq = [ x | (x, y) <- zip seq $ tail seq, x < y ]
I also tried changing the type declaration to the below, but that didn't work either.
test :: (Num n, Ord n) => [Maybe n] -> [Num (Maybe n)]
I'm not really sure how to go about fixing this error. I'm fairly new to Haskell, so it might just be something really simple that I'm missing, or that I've structured everything completely wrong, but this is stumping me. What am I doing wrong?