首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数中的Haskell getLine,否则

函数中的Haskell getLine,否则
EN

Stack Overflow用户
提问于 2018-10-28 22:58:44
回答 2查看 611关注 0票数 0

我对Haskell非常陌生,我正在尝试学习一些简单的函数。

我通过这样的函数做出了一些选择:

代码语言:javascript
复制
displayOptions :: Int -> String
displayOptions option
    | option == 0 = "1 - Shop\n2 - Fight Monsters\n3 - Inn\n4 - Monk"
    | otherwise = "invalid"

然后使用getLine获取用户输入。

代码语言:javascript
复制
choice <- getLine

然后显示第二个选项框,例如,

代码语言:javascript
复制
playerChoice :: String -> String
playerChoice option
    | option == "1" = "Sword - 50gp\nShield - 100gp"
    | option == "2" = "You go fight some monsters outside town."
    | option == "3" = "You go to the town Inn."
    | option == "4" = "You go see the holy monk."
    | otherwise = "You entered invalid information...\n" ++ displayOptions(0)

我感到困惑的是如何在函数中再次获得用户的选择。我希望我的otherwise =说出无效的信息,显示选项,再次获得输入,然后显示他们所做的选择。

所以我的主程序应该是这样的:

代码语言:javascript
复制
main = do
    putStrLn "The king has sent you on the journey to become a master."
    putStrLn $ "What would you like to do?"
    putStrLn $ displayOptions(0)
    choice <- getLine
    putStrLn $ playerChoice(choice)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-28 23:06:59

您必须将返回类型更改为IO字符串,而不是字符串。

但是,您可能希望返回任何一个字符串,以便该函数指示它返回了游戏进程文本Right "You do something"或一个失败,并解释了失败Left "Not an option"

然后在调用者中循环,直到得到一个Right值,每次得到一个Left值,就会打印文本并再次询问。

我确信有一个稍微好一点的方法,但下面是一些快速修复代码:

代码语言:javascript
复制
module Main where

playerChoice :: String -> Either String String
playerChoice option
    | option == "1" = Right "Sword - 50gp\nShield - 100gp"
    | option == "2" = Right "You go fight some monsters outside town."
    | option == "3" = Right "You go to the town Inn."
    | option == "4" = Right "You go see the holy monk."
    | otherwise = Left "You entered invalid information..."

displayOptions :: Int -> String
displayOptions option
    | option == 0 = "1 - Shop\n2 - Fight Monsters\n3 - Inn\n4 - Monk\n"
    | otherwise = "invalid"

main = do
    let progress whathappens = do
        putStrLn whathappens
        let tryAsk prompt = do
            putStrLn prompt
            choice <- getLine
            either tryAsk progress $ playerChoice(choice)
        tryAsk $ displayOptions(0) ++ "What would you like to do?"
    progress "The king has sent you on the journey to become a master."

如果您是import Data.Function,那么您也可以像下面这样编写它--在本例中可能不是更好,但这是进入haskell迷人部分的一个不错的浅表步骤:

代码语言:javascript
复制
fix (\moreProgress whathappens -> do
    putStrLn whathappens
    fix (\askAgain prompt -> do
        putStrLn prompt
        choice <- getLine
        either askAgain moreProgress $ playerChoice(choice))
        $ displayOptions(0) ++ "What would you like to do?")
    $ "The king has sent you on the journey to become a master."
票数 3
EN

Stack Overflow用户

发布于 2018-10-28 23:10:29

  1. 您应该将返回类型更改为Either String String,以便提供错误消息。有关更多细节,请查看Either类型的文档。
  2. 在Haskell中,我们没有像forwhile这样的传统循环结构,而是使用递归调用。有关示例,请参见While loop in Haskell with a condition
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53036807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档