所以我刚开始学习haskell,我正在尝试使用这个if语句:
[if (((mod x 3) == 0) && ((mod x 5) == 0)) then "Fizzbuzz" else x | x <- [1..50]]
但是当我在ghci中编译时,我收到以下错误:
No instance for (Integral [Char])
arising from a use of `mod' at baby.hs:22:19-25
Possible fix: add an instance declaration for (Integral [Char])
In the first argument of `(==)', namely `(mod x 3)'
In the first argument of `(&&)', namely `((mod x 3) == 0)'
In the expression: (((mod x 3) == 0) && ((mod x 5) == 0))
Failed, modules loaded: none.
好的,所以我发现x被推断为一个字符串,因为if返回一个显式字符串,因此整个函数不起作用。那我怎么能真正解决这个问题呢? (我知道我的问题是愚蠢的,但我不习惯使用功能范例或使用类型推断进行静态输入)。
答案 0 :(得分:7)
'then'和'else'分支必须具有相同的类型。 "Fizzbuzz"
是一个字符串,其中x
是Int。如果您打算打印结果,只需将show x
放入else
分支。
也许最好添加到Haskell的common misunderstandings的if / then / else部分。出于同样的原因,else
分支必须存在,它也必须与then
具有相同的类型。
答案 1 :(得分:4)
问题不在于此部分代码。错误消息是关于mod的类型mod :: (Integral a) => a -> a -> a
,但x应该是[Char]类型。
我猜这里推断出x的类型(因为类型应该是Int)。因此,为了调试问题,我建议您声明函数的类型,如下所示:
f :: Int -> ...
f x ... = if (((mod x 3) == 0) && ((mod x 5) == 0))...
如果您仍有问题,请发布其余代码。
答案 2 :(得分:2)
您只需添加show即可将Int转换为String。
[if mod x 3 == 0 && mod x 5 == 0 then "Fizzbuzz" else show x | x <- [1..50]]
反过来可以写成:
map (\x -> if mod x 15 == 0 then "Fizzbuzz" else show x) [1..50]
答案 3 :(得分:-1)
main = mapM_ (putStrLn . fb) [1..100]
fb :: Int -> String
fb x | [3,5] `divides` x = "fizzbuzz"
| [5] `divides` x = "buzz"
| [3] `divides` x = "fizz"
| otherwise = show x
divides :: [Int] -> Int -> Bool
xs `divides` y = y `mod` product xs == 0
答案 4 :(得分:-3)
从它的外观来看,你正在尝试解决ProjectEuler的问题1.尝试以其中缀形式使用“mod”函数,即如下:
if ((x `mod` 3 == 0) && (x `mod` 5 == 0)) then blah blah
我认为这将迫使编译器认为x将成为Int。否则,您将不得不向我们提供更多信息,例如KennyTM,luqui和TomMD建议(可能错误是在其他地方)!