帮助解决使用警卫的问题 - 使用CODE更新

时间:2010-12-09 03:28:29

标签: haskell

我在函数内使用了防护,但在函数签名后没有立即使用。守卫在函数体内的 do 语句下。我收到这个错误:

parse error on input `|'

我想也许错误来自缩进,但我尝试了很多缩进,但我仍然得到错误。我问的是因为在功能签名之后警卫不是立即就是为什么我会得到错误?

感谢

更新1

CODE: 用户可以猜测一个数字,如果它们相同,则将该数字与随机数进行比较。如果不正确,则用户将猜测直到函数中的“guess”变量为零。在每个阶段,价值(猜测)减少一个。

例如:puzz 12 5。用户可以猜测五次,随机数将在1到12之间被选中。这就是函数的假设,但它不起作用。

puzz :: Int -> Int -> IO ()
puzz boundary guess = do
                          putStr "Guess" 
                          -- putStr  -- I have to print (1 .. guess) here in each iteration
                          putStr ":"
                          x <- randomRIO (1, boundary :: Int)
                          n <- getLine
                          let
                             nTo = read n::Int
                            in print x
                               | guess == 0 = putStr "You couldn't guess right,the   correct answer is" ++ x
                               | nTo > x = putStr "lower"
                               | nTo < x = putStr "higer"
                               | nTo == x =  putStr "Congrat, You guess right."
                               | otherwise raad boundary (guess - 1)

输出必须是这样的:

Main> puzz 50 6
Guess a number betwee 1 en 50.
Guess 1: 49
lower
Guess 2: 25
lower
Guess 3: 12
higher
Guess 4: 18
higher
Guess 5: 21
higher
Guess 6: 23
lower
You couldn't guess correct, the answer was: 22.

感谢您的帮助

2 个答案:

答案 0 :(得分:5)

您使用的警卫不正确。 From the report

  

案例表达式中的顶级模式和函数或模式绑定中的顶级模式集可能具有零个或多个关联的警卫。

因此它们仅用于案例和功能绑定。如果你只想简明地介绍一系列真假测试,那么在一个记号内,也许case () of ()技巧可行:

main = do
    putStrLn "hello world"
    n <- getLine
    let nTo = read n :: Int
    case ()
      of () | cond -> putStrLn "foo"
            | cond' -> putStrLn "bar"
            | otherwise -> putStrLn "baz"

答案 1 :(得分:1)

应该注意的是,除了使用保护错误之外,还有一些事情与您的代码有点不同。默认情况下,输出在haskell中缓冲,因此如果您希望Guess与输入位于同一行,则必须说stdOut不应该缓冲(hSetBuffering stdOut NoBuffering),或者您必须使用{{1}刷新输出}。没有必要编写hFlush,编译器知道它是一个Int。这是一个更完整的例子,我确信它可以做得更好,但至少它可行:

boundary :: Int