我试图弄清楚我在以下代码中遇到的多个Haskell错误。这是我的欧拉问题#1的代码:
module Lib
( euler1
) where
modTest x = mod 3 x == 0 || mod 5 x == 0
euler1 :: IO ()
euler1 = do
let b = sum $ filter modTest $ [1,2..999]
putStrLn $ "result: " ++ b
我收到以下三个错误:
/home/kuwze/src/haskell/euler-hs/src/Lib.hs:9:11: error:
• No instance for (Num [Char]) arising from a use of ‘sum’
• In the expression: sum $ filter modTest $ [1, 2 .. 999]
In an equation for ‘b’: b = sum $ filter modTest $ [1, 2 .. 999]
In the expression:
do { let b = sum $ filter modTest $ ...;
putStrLn $ "result: " ++ b }
/home/kuwze/src/haskell/euler-hs/src/Lib.hs:9:24: error:
• No instance for (Integral [Char]) arising from a use of ‘modTest’
• In the first argument of ‘filter’, namely ‘modTest’
In the expression: filter modTest
In the second argument of ‘($)’, namely
‘filter modTest $ [1, 2 .. 999]’
/home/kuwze/src/haskell/euler-hs/src/Lib.hs:9:34: error:
• No instance for (Enum [Char])
arising from the arithmetic sequence ‘1, 2 .. 999’
• In the second argument of ‘($)’, namely ‘[1, 2 .. 999]’
In the second argument of ‘($)’, namely
‘filter modTest $ [1, 2 .. 999]’
In the expression: sum $ filter modTest $ [1, 2 .. 999] Failed, modules loaded: none.
我知道这是一个简单的问题,但我真的很感激任何帮助。非常感谢你。
答案 0 :(得分:9)
tl; dr :打印时使用show b
。
不幸的是,这里的错误不是太大。我会解释它的来源。
module Lib
( euler1
) where
modTest x = mod 3 x == 0 || mod 5 x == 0
euler1 :: IO ()
euler1 = do
let b = sum $ filter modTest $ [1,2..999]
putStrLn $ "result: " ++ b
Haskell会看到你的let b = ...
行,并注意到,无论b
是什么,它都必须是一些数字的整数类型。那一切都很好;你想要那个。但是你做"result: " ++ b
并且Haskell看到b
必须是一个字符串。所以它试图合理化这个:字符串是数字类型吗?答案是否定的(除非你定义了一个非常奇怪的实例),这就是为什么你得到Num [Char]
(或等效Num String
)不起作用的错误。您只需要告诉Haskell show
您的数值,将其转换为字符串。
putStrLn $ "result: " ++ show b
将来,如果您收到的错误看起来令人困惑(例如,您在此处获得的错误会为您提供无效的行号),请尝试使用显式类型签名。例如,如果您希望b
为整数,但是您遇到错误,请尝试
let b = (sum $ filter modTest $ [1,2..999]) :: Int
然后你应该得到更准确的错误信息,因为Haskell更了解你的意图。修复问题后,如果它们使代码混乱,可以删除内联类型注释,但它们对调试非常有帮助。