【发布时间】:2018-07-17 05:48:51
【问题描述】:
我实际上正在学习 Haskell,我正在尝试制作一个简单的 FizzBuzz Kata。
这个想法是将一个数字列表作为条目,并生成一个数字列表 |遵循以下规则的字符串:
- fizzBuzz:: [StringInt] -> [StringInt]
- 每 3 的倍数,列表中的项目应为“Fizz”
- 每 5 的倍数,列表中的项目应为“Buzz”
- 否则应该是数字
这里是我生成的代码:
module FizzBuzz where
data StringInt a = Int a | String a
handleRule:: StringInt a -> a
handleRule x
| x % 3 == 0 = StringInt "Fizz"
| x % 5 == 0 = StringInt "Buzz"
| otherwise = x
run:: [StringInt a] -> [a]
run = map handleRule
在尝试运行以下测试时:
module FizzBuzzSpec (spec) where
import Test.Hspec
import FizzBuzz
spec :: Spec
spec = describe "FizzBuzz#run" $ do
it "should have displayed Fizz for number 3" $
run [1..10]:2 `shouldBe` "Fizz"
it "should have displayed Buzz for number 5" $
run [1..10]:4 `shouldBe` "Buzz"
我有以下输出:
• Occurs check: cannot construct the infinite type: a ~ StringInt a
• In the expression: x
In an equation for ‘handleRule’:
handleRule x
| (%) x 3 == 0 = StringInt "Fizz"
| (%) x 5 == 0 = StringInt "Buzz"
| otherwise = x
• Relevant bindings include
x :: StringInt a (bound at src/FizzBuzz.hs:6:12)
handleRule :: StringInt a -> a (bound at src/FizzBuzz.hs:6:1)
| 9 | |否则 = x
重要提示:我真的是一个 Haskell 新手,如果我在那里做出可怕的事情,请见谅。
你知道我做错了什么吗?
编辑:
我尝试过使用:
module FizzBuzz where
type StringInt = Either Int String
handleRule:: Int -> StringInt
handleRule x
| x `mod` 3 == 0 = Right "Fizz"
| x `mod` 5 == 0 = Right "Buzz"
| otherwise = Left x
run:: [Int] -> [StringInt]
run = map handleRule
还有
module FizzBuzzSpec (spec) where
import Test.Hspec
import FizzBuzz
spec::Spec
spec = describe "FizzBuzz#run" $ do
it "should have displayed Fizz for number 3" $
run [1..10]:2 `shouldBe` Right "Fizz"
it "should have displayed Buzz for number 5" $
run [1..10]:4 `shouldBe` Right "Buzz"
但这总是抛出
• Couldn't match expected type ‘[[StringInt]]’
with actual type ‘Either a0 [Char]’
• In the second argument of ‘shouldBe’, namely ‘Right "Fizz"’
In the second argument of ‘($)’, namely
‘run [1 .. 10] : 2 `shouldBe` Right "Fizz"’
In a stmt of a 'do' block:
it "should have displayed Fizz for number 3"
$ run [1 .. 10] : 2 `shouldBe` Right "Fizz"
|
9 | run [1..10]:2 `shouldBe` Right "Fizz"
| ^^^^^^^^^^^^
/Users/pc/Soft/haskell/hello-stack/test/FizzBuzzSpec.hs:11:50: error:
• Couldn't match expected type ‘[[StringInt]]’
with actual type ‘Either a1 [Char]’
• In the second argument of ‘shouldBe’, namely ‘Right "Buzz"’
In the second argument of ‘($)’, namely
‘run [1 .. 10] : 4 `shouldBe` Right "Buzz"’
In a stmt of a 'do' block:
it "should have displayed Buzz for number 5"
$ run [1 .. 10] : 4 `shouldBe` Right "Buzz"
|
11 | run [1..10]:4 `shouldBe` Right "Buzz"
|
^^^^^^^^^^^^
无法从这里得到重点......
感谢你们的帮助
【问题讨论】:
-
如果你想访问一个列表的元素,不要使用 :,使用 !!例如:([1..10] !! 2) == 3
-
不要忘记有些数字是 3 和 5 的倍数。在 FizzBuzz 的某些变体中,处理这种情况是练习的重点。
-
是的,谢谢:)。似乎守卫是解决这个问题的好方法。怀俄明?
标签: haskell