haskell - 'do' block 内的守卫 - haskell

标签 haskell syntax do-notation guard-clause

我想编写一个简单的游戏“猜数字” - 尝试 n 次。我想添加一些条件和命中。是否可以在 do block 内使用 guards

这是我的代码:

game = return()
game n = do putStrLn "guess number: 0-99"
            number<-getLine
            let y = read number
            let x =20
            | y>x = putStrLn "your number is greater than x"
            | y<x = putStrLn "your number is less than x"
            | y==x  putStrLn "U win!!"
            | otherwise = game (n-1)

已经有错误

error: parse error on input ‘|’

是否可以通过一些空白来修复,或者根本无法做到?

最佳答案

一个 do expression [Haskell-report]仅由 exp 组成, pat <- exp ,和let …语句,编译器将对这些语句进行脱糖处理。因此,如果没有一些语言扩展,您就无法在 do 中编写防护程序。堵塞。此外,无论如何启用它可能不是一个好主意。例如,如果您想使用两个相邻的“防护 block ”怎么办?然后两者将“合并”,因此第一个 block 的守卫将已经消除(几乎)所有情况。

您可以使用另一个let此处的子句:

game :: IO ()
game 0 = return ()
game n = do
    putStrLn "guess number: 0-99"
    number <- getLine
    let y = read number
    let x = 20
    <b>let action</b> | y > x = putStrLn "your number is greater than x" >> game (n-1)
               | y < x = putStrLn "your number is less than x" >> game (n-1)
               | otherwise = putStrLn "U win!!"
    <b>action</b>

请注意 otherwise原始问题中的值永远不会被触发,因为一个值小于、大于或等于另一个值。

关于haskell - 'do' block 内的守卫 - haskell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59778472/

相关文章:

Haskell io-streams 和 `forever` 不向标准输出产生输出

haskell - 静态链接使用 C++ 包装器库的 haskell 程序

ruby - 没有目标对象的 case 表达式 : should it be used?

haskell - 如何有条件地绑定(bind)在 do block 中?

haskell - Haskell 能在数字母方面打败 C 吗?

bash - 为什么 Bash 中 '[' 和 ']' 周围要有空格?

r - R 中 for 循环的语法

haskell - 添加操作而不更改结果以重构 do-notation

haskell - 重构使用 Reader monad 的 Haskell 函数

Haskell:将lambda表达式与绑定(bind)函数一起使用时的变量范围