7

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

这是我的代码:

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 ‘|’

它可以用一些空白来修复,还是不可能做到?

4

4 回答 4

12
于 2020-01-16T22:14:49.533 回答
8

那里有很多问题。

首先,你不能说game =某事game n =某事,所以删除该game = return ()行。(您可能一直在尝试编写类型签名,但这不是一个。)

其次,您不能在任意位置使用保护语法。与您编写的内容最接近的有效内容是多路 if-expressions,它可以让您编写以下代码:

{-# LANGUAGE MultiWayIf #-}
game n = do putStrLn "guess number: 0-99"
            number<-getLine
            let y = read number
            let x =20
            if
              | 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)

第三,Ord类型类应该用于具有总顺序的类型,因此除非您使用像 NaN 这样的非法事物,否则您将始终拥有 、 或 中的一个y>xy<x因此y==x永远otherwise不会输入 。

第四,与<==和比较>是单调且缓慢的,因为它必须不断重复比较。而不是这样做,做这样的事情:

case y `compare` x of
  GT -> _
  LT -> _
  EQ -> _
于 2020-01-16T22:14:13.257 回答
4

You could also just use case or LambdaCase.

{-# LANGUAGE LambdaCase #-}

game  :: Int -> IO ()
game n = case n of
  0 -> putStrLn "used all attempts"
  n -> 
    putStrLn "guess a number: 0 - 99" >>
    (`compare` 20) . read <$> getLine >>= 
      \case 
        EQ -> putStrLn "U win"
        GT -> putStrLn "your number is greater than x" >> 
              game (n - 1)
        LT -> putStrLn "your number is less than x" >> 
              game (n - 1)
于 2020-01-18T01:27:57.847 回答
0

The other answers are very informative. Reading those led me to see that you can also call a function to solve this, e.g.

game = do putStrLn "guess number: 0-99"
          number<-getLine
          let y = read number
          let x = 20
          action y x
       where
           action y x 
            | y>x = putStrLn "your number is greater than x" >> game
            | y<x = putStrLn "your number is less than x" >> game
            | otherwise = putStrLn "U win!!"
于 2021-10-20T01:13:16.347 回答