ここでの問題は何ですか?
module Main
where
import System.IO
main = do
hSetBuffering stdin LineBuffering
numbers <- ask -- parse error on input `numbers'
putStrLn "The sum of all numbers is:"
putStrLn $ sum numbers
putStrLn "The product of all numbers is:"
putStrLn $ product numbers
ask :: (Read a, Eq a, Num a) => IO [a]
ask = do
putStrLn "Enter a number to add it to the list. Enter zero to terminate the list."
input <- getLine
let n = read input
if n == 0
then return []
else do
rest <- ask
return (n : rest)
の型シグネチャを見てみましょうputStrLn
:
> :t putStrLn
putStrLn :: String -> IO ()
a
inにask
は明示的な型シグネチャがないため、Haskell / GHCはそれを使用するメソッドからそれを推測します。
したがって、メソッドがあるためputStrLn a
、これが可能な唯一の方法は、の場合a :: String
です。
ただし、の型シグネチャではsum
:
> :t sum
sum :: (Num a) => [a] -> a
a
Num
タイプクラスのインスタンスである必要があります。(ask
関数もこれを指定します)。
GHCは、それが...でa
なければならないことを知っていString
ますが、がsum
必要Num
です。String
少なくとも前奏曲では、のインスタンスではありませんNum
。
ここに矛盾が現れます。
プログラムghc-mod
をチェックするようなプログラムを使用することをお勧めします。より役立つエラーメッセージが表示される場合があります。これが私が得たものです:
No instance for (Num String)
これは私たちが結論したこととよく一致しています。
この場合の解決策は、最初にあなたNum
をString
:に変えることです。
> :t show
show :: (Show a) => a -> String
ために:
putStrLn $ show $ sum numbers
幸いなことに、printStrLn . show
エイリアスはprint
次のとおりです。
> :t print
print :: (Show a) => a -> IO ()
だからあなたは使うことができます
print $ sum numbers
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加