私は現在、Haskell を学ぼうとしているところですが、Maybe
モナドに関する奇妙な問題に遭遇しました。
実験として、私は現在、文字列を取得し、各文字を任意の数値に変換し、それらを乗算/結合しようとしています。これが私がこれまでに持っているものです:
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"
これを実行しようとすると、次のエラーが返されます。
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]
なぜこのエラーが発生するのか、またはそれが正確に何を意味するのかは 100% わかりませんが、2 つのMaybe
モナドを乗算しようとしている可能性があると思われtest
ます。そしてうまく動作します:
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
test seq = [ x | (x, y) <- zip seq $ tail seq, x < y ]
また、型宣言を以下に変更してみましたが、それもうまくいきませんでした。
test :: (Num n, Ord n) => [Maybe n] -> [Num (Maybe n)]
このエラーを修正する方法がよくわかりません。私はHaskellにかなり慣れていないので、本当に単純なものが欠けているか、すべてが完全に間違って構成されている可能性がありますが、これは私を困惑させています. 私は何を間違っていますか?