我正在尝试使用列表推导在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"; 你的代码似乎略有不同.
ham*_*mar 11
首先,你错过了表达式的else各个部分if.在Haskell中,if是表达式,而不是语句,因此该else部分是必需的.
其次,如果所有保护表达式都评估为,则列表推导仅产生任何值True.1到20之间没有数字,模数为3,4和5,因此您将得不到任何结果.您将要使用||(逻辑OR)来组合它们.
第三,如果不满足任何其他条件,FizzBuzz的大多数定义都希望您返回该数字.在这种情况下,您将要使用show将数字转换为a String.
这是另一个可以扩展到任意数量替换的版本:
\n\nfizzbuzz\' :: [(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\nRun Code Online (Sandbox Code Playgroud)\n\n您可以内联在的子句fizzbuzz\'中,但我发现一个单独的函数更容易测试。wherefizzbuzz
你可以像这样运行它:
\n\n\xce\xbb> mapM_ putStrLn $ map (fizzbuzz [(3, "fizz"), (5, "buzz")]) [9..15]\nfizz\nbuzz\n11\nfizz\n13\n14\nfizzbuzz\nRun 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\nRun Code Online (Sandbox Code Playgroud)\n