'do'街区内的后卫 - 哈斯克尔



我想写一个简单的游戏"猜数" -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 ‘|’

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

一个do表达式 [Haskell-report] 只包含exppat <- explet …语句,编译器会对这些语句进行脱糖。因此,如果没有一些语言扩展,您就无法在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 ()行。(您可能一直在尝试编写类型签名,但这不是一个。

其次,您不能在任意位置使用保护语法。与你写的最接近的有效东西是多向 if 表达式,它可以让你写这个:

{-# 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)

第三,Ordtypeclass 应该是针对具有全序的类型,所以除非你使用像 NaN 这样非法的东西,否则你将始终拥有y>xy<xy==x中的一个,所以otherwise永远不会被输入。

第四,与<==>进行比较是不合时宜和缓慢的,因为它必须不断重复比较。与其这样做,不如做这样的事情:

case y `compare` x of
GT -> _
LT -> _
EQ -> _

您也可以只使用caseLambdaCase

{-# 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)

其他答案非常有用。阅读这些让我看到你也可以调用一个函数来解决这个问题,例如

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!!"

相关内容

  • 没有找到相关文章

最新更新