我想编写一个简单的游戏“猜号码”-尝试n
。我想添加一些条件和点击。是否可以在do
块内使用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]仅由do
,exp
和pat < exp
语句组成,并且编译器将对它们进行解糖。因此,如果没有某些语言扩展,则无法在let …
块中编写防护。此外,启用该功能可能不是一个好主意。例如,如果您想彼此相邻使用两个“防护块”怎么办?然后这两个将“合并”,因此第一个块的警卫将已经(几乎)清除所有情况。
您可以在此处使用另一个do
子句:
let
请注意,原始问题中的game :: IO ()
game 0 = return ()
game n = do
putStrLn "guess number: 0-99"
number <- getLine
let y = read number
let x = 20
let action | 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!!"
action
永远不会被触发,因为一个值小于,大于或等于另一个值。
那里有很多问题。
首先,您不能说otherwise
和game =
,因此请删除game n =
行。 (您可能一直在尝试编写类型签名,但这不是一个。)
第二,您不能在任意地方使用警卫语法。与您写的内容最接近的有效内容是game = return ()
,可以让您编写以下内容:
multi-way 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)
类型类应该用于具有总顺序的类型,因此,除非您使用的是诸如NaN之类的非法内容,否则您将始终拥有Ord
,y>x
或y<x
中的一种,因此将永远不会输入y==x
。
第四,与otherwise
,<
和==
进行比较是单项且缓慢的,因为它必须不断重复比较。不要这样做,而是执行以下操作:
>
您也可以只使用case y `compare` x of
GT -> _
LT -> _
EQ -> _
或case
。
LambdaCase