在 Haskell 的函数中实现输入变量

Implementing input variables in functions in Haskell

这是我之前 的延续。

我正在创建一个允许输入 3 个参数的 FizzBu​​zz 函数。然而,这不仅仅是标准的 FizzBu​​zz 程序。这个允许 2 个除数,同时实现一个上限。因此,如果 div1 可整除打印 "Fizz",如果 div2 可整除打印 "buzz",如果 div1div2 可整除打印 "FizzBuzz",否则打印 number/integer。

我在 Haskell 中找到了展示如何执行常规 FizzBu​​zz 的不同教程,并将其修改为能够按照上述说明执行。

现在我遇到了一个错误,我不确定如何在 Haskell 中正确执行此操作。

fizzbuzz' :: [(Integer, String)] -> Integer -> String
fizzbuzz' ss n = foldl (\str (num, subst) -> if n `mod` num == 0 then str ++ subst else str ++ "") "" ss

fizzbuzz :: [(Integer, String)] -> Integer -> String
fizzbuzz ss n = if null str then show n else str
  where str = fizzbuzz' ss n

fb :: Integer -> Integer -> Integer -> Integer
fb x y z = mapM_ putStrLn $ map (fizzbuzz [(x, "fizz"), (y, "buzz")]) [0..z]

我得到的错误是:

Couldn't match expected type ‘Integer’ with actual type ‘IO ()’
In the expression:
  mapM_ putStrLn $ map (fizzbuzz [(x, "fizz"), (y, "buzz")]) [0 .. z]
In an equation for ‘fb’:
    fb x y z
      = mapM_ putStrLn
        $ map (fizzbuzz [(x, "fizz"), (y, "buzz")]) [0 .. z]
Failed, modules loaded: none.

有什么想法吗?

问题出在 fb 的类型签名上。只需删除它,您的代码就会编译。

fb 的正确类型签名是 Integer -> Integer -> Integer -> IO (),您可以通过 ghci 使用 :t 命令告诉您来验证:

$ ghci Fizzbuzz.hs
Prelude> :t fb
fb :: Integer -> Integer -> Integer -> IO ()
Prelude>