哈斯克尔的fizzbuzz?

Pau*_*l J 3 haskell fizzbuzz

我正在尝试使用列表推导在haskell中编写'fizzbuzz'.

以下为什么不工作,应该怎么做?

[ if x `mod` 5 == 0 then "BUZZFIZZ"
  if x `mod` 3 == 0 then "BUZZ" 
  if x `mod` 4 == 0 then "FIZZ" | x <- [1..20], 
    x `mod` 3 == 0, 
    x `mod` 4 == 0, 
    x `mod` 5 == 0 ]
Run Code Online (Sandbox Code Playgroud)

- 更新 -

好的,这有效:

[ if x `mod` 5 == 0 then "BUZZFIZZ"
        else
          if x `mod` 3 == 0 then "BUZZ" 
          else
          if x `mod` 4 == 0 then "FIZZ" else show x
          | x <- [1..25]]
Run Code Online (Sandbox Code Playgroud)

谢谢

Joh*_*n L 39

这不是有效的Haskell.该else分支是不可选的if ... then ... else.而不是使用if,这似乎是使用case声明的好机会.

case (x `rem` 3, x `rem` 5) of
  (0,0) -> "fizzbuzz"
  (0,_) -> "fizz"
  (_,0) -> "buzz"
  _     -> show x
Run Code Online (Sandbox Code Playgroud)

这个片段适用于传统的"fizzbuzz"; 你的代码似乎略有不同.

  • 你有fizzbuzz O_o*part*的230个代表 (2认同)

ham*_*mar 11

首先,你错过了表达式的else各个部分if.在Haskell中,if是表达式,而不是语句,因此该else部分是必需的.

其次,如果所有保护表达式都评估为,则列表推导仅产生任何值True.1到20之间没有数字,模数为3,4和5,因此您将得不到任何结果.您将要使用||(逻辑OR)来组合它们.

第三,如果不满足任何其他条件,FizzBu​​zz的大多数定义都希望您返回该数字.在这种情况下,您将要使用show将数字转换为a String.


Mic*_*ohl 5

这是另一个可以扩展到任意数量替换的版本:

\n\n
fizzbuzz\' :: [(Integer, String)] -> Integer -> String\nfizzbuzz\' ss n = foldl (\\str (num, subst) -> if n `mod` num == 0 then str ++ subst else str ++ "") "" ss\n\nfizzbuzz :: [(Integer, String)] -> Integer -> String\nfizzbuzz ss n = if null str then show n else str\n  where str = fizzbuzz\' ss n\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以内联在的子句fizzbuzz\'中,但我发现一个单独的函数更容易测试。wherefizzbuzz

\n\n

你可以像这样运行它:

\n\n
\xce\xbb> mapM_ putStrLn $ map (fizzbuzz [(3, "fizz"), (5, "buzz")]) [9..15]\nfizz\nbuzz\n11\nfizz\n13\n14\nfizzbuzz\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者进行额外的替换:

\n\n
\xce\xbb> mapM_ putStrLn $ map (fizzbuzz [(3, "fizz"), (5, "buzz"), (7, "dazz")]) [19..24]\n19\nbuzz\nfizzdazz\n22\n23\nfizz\n
Run Code Online (Sandbox Code Playgroud)\n