我还在学习Haskell,我想知道是否有一种不那么冗长的方式来使用一行代码来表达以下语句:
map (\x -> (x, (if mod x 3 == 0 then "fizz" else "") ++
if mod x 5 == 0 then "buzz" else "")) [1..100]
产地:
[(1,""),(2,""),(3,"fizz"),(4,""),(5,"buzz"),(6,"fizz"),(7,""),(8,""),(9,"fizz"),(10,"buzz"),(11,""),(12,"fizz"),(13,""),(14,""),(15,"fizzbuzz"),(16,""),(17,""),(18,"fizz"),(19,""),(20,"buzz"),(21,"fizz"),(22,""),(23,""),(24,"fizz"),(25,"buzz"),(26,""),(27,"fizz"),(28,""),(29,""),(30,"fizzbuzz")
等等
我觉得我的语法比我应该更多。我在Haskell中已经看到了其他问题,但是我正在寻找在单个语句中表达这一点的最佳方式(试图理解如何更好地处理语法)。
答案 0 :(得分:10)
我们不需要stinkin'mod
...
zip [1..100] $ zipWith (++) (cycle ["","","fizz"]) (cycle ["","","","","buzz"])
或略短
import Data.Function(on)
zip [1..100] $ (zipWith (++) `on` cycle) ["","","fizz"] ["","","","","buzz"]
或蛮力方式:
zip [1..100] $ cycle ["","","fizz","","buzz","fizz","","","fizz","buzz","","fizz","","","fizzbuzz"]
答案 1 :(得分:7)
如果你坚持单行:
[(x, concat $ ["fizz" | mod x 3 == 0] ++ ["buzz" | mod x 5 == 0]) | x <- [1..100]]
答案 2 :(得分:4)
怎么样......
fizzBuzz = [(x, fizz x ++ buzz x) | x <- [1..100]]
where fizz n | n `mod` 3 == 0 = "fizz"
| otherwise = ""
buzz n | n `mod` 5 == 0 = "buzz"
| otherwise = ""
答案 3 :(得分:2)
无法抗拒向另一个方向前进并使其变得更加复杂。看,没有mod
......
merge as@(a@(ia,sa):as') bs@(b@(ib,sb):bs') =
case compare ia ib of
LT -> a : merge as' bs
GT -> b : merge as bs'
EQ -> (ia, sa++sb) : merge as' bs'
merge as bs = as ++ bs
zz (n,s) = [(i, s) | i <- [n,2*n..]]
fizzBuzz = foldr merge [] $ map zz [(1,""), (3,"fizz"), (5,"buzz")]
答案 4 :(得分:1)
与larsmans的回答一样:
fizzBuzz = [(x, f 3 "fizz" x ++ f 5 "buzz" x) | x <- [1..100]]
where f k s n | n `mod` k == 0 = s
| otherwise = ""
答案 5 :(得分:1)
我认为您认为自己正在与语法作斗争的原因是因为您混合了太多类型。
而不是试图打印:
[(1, ""), (2,""), (3,"Fizz")...]
想想打印字符串:
["1","2","Fizz"...]
我的尝试:
Prelude> let fizzBuzz x | x `mod` 15 == 0 = "FizzBuzz" | x `mod` 5 == 0 = "Buzz" | x `mod` 3 == 0 = "Fizz" | otherwise = show x
Prelude> [fizzBuzz x | x <-[1..100]]
["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"...]
要将Int转换为String,请使用:
show x
答案 6 :(得分:1)
仅供学习
zipWith (\a b -> b a) (map show [1..100]) $ cycle [id,id,const "fizz",id,const "buzz",const "fizz",id,id,const "fizz",const "buzz",id,const "fizz",id,id,const "fizzbuzz"]
产生
["1","2","fizz","4","buzz","fizz","7","8","fizz","buzz","11","fizz","13","14","fizzbuzz","16","17","fizz","19","buzz","fizz","22","23","fizz","buzz","26","fizz","28","29","fizzbuzz","31","32","fizz","34","buzz","fizz","37","38","fizz","buzz","41","fizz","43","44","fizzbuzz","46","47","fizz","49","buzz","fizz","52","53","fizz","buzz","56","fizz","58","59","fizzbuzz","61","62","fizz","64","buzz","fizz","67","68","fizz","buzz","71","fizz","73","74","fizzbuzz","76","77","fizz","79","buzz","fizz","82","83","fizz","buzz","86","fizz","88","89","fizzbuzz","91","92","fizz","94","buzz","fizz","97","98","fizz","buzz"]
答案 7 :(得分:0)
作家monad看起来不错(如果你不喜欢concat
):
fizzBuzz = [(x, execWriter $ when (x `mod` 3 == 0) (tell "fizz") >> when (x `mod` 5 == 0) (tell "buzz")) | x <- [1..100]]
虽然不是特别简洁。