【问题标题】:Haskell, using multiple if statements on input and output IOHaskell,在输入和输出 IO 上使用多个 if 语句
【发布时间】:2013-04-17 00:38:06
【问题描述】:

这是我当前的代码,我希望能够创建一个充当接口的 MAIN IO,并允许用户根据自己的选择选择要执行的函数。

type Title = String
type Actor = String
type Cast = [Actor]
type Year = Int
type Fan = String
type Fans = [Fan]
type Period = (Year, Year)
type Film = (Title, Cast, Year, Fans)
type Database = [Film]
title (t, _, _, _) = t
cast (_, c, _, _) = c
year (_, _, y, _) = y
fans (_, _, _, fs) = fs

testDatabase :: Database
testDatabase = [("Casino Royale", ["Daniel Craig", "Eva Green", "Judi Dench"], 2006, ["Garry", "Dave", "Zoe", "Kevin", "Emma"]),
    ("Cowboys & Aliens", ["Harrison Ford", "Daniel Craig", "Olivia Wilde"], 2011, ["Bill", "Jo", "Garry", "Kevin", "Olga", "Liz"]),     
        ("Catch Me If You Can", ["Leonardo DiCaprio", "Tom Hanks"], 2002, ["Zoe", "Heidi", "Jo", "Emma", "Liz", "Sam", "Olga", "Kevin", "Tim"])]

功能1:

displayAllFilms' :: [Film] -> String -> String
displayAllFilms' [] filmString = filmString
displayAllFilms' ((title,cast,year,fans):films) filmString = 
       displayAllFilms' films (filmString ++ "\n" ++ title ++ ", " ++ listStuff cast ", " ++ (show year) ++ ", " ++ show (length fans))

功能2:

filmsByFan f = map title $ filter (elem f . fans) testDatabase

以上代码 100% 正常工作,我能够从给定数据库中提取信息。

这是我创建的示例 MAIN IO:

main :: IO ()
main = do putStrLn "What function would you like to execute? 1. addFilm / 2.displayAllFilms / 3. filmsByYear / 4. filmsByFan / 5. filmsByActor Period / 6. becomeFan: "
          str <- getLine
          if str /= "2"
            then return ()
            else do putStrLn (displayAllFilms' testDatabase str)
          if str /= "4"
            then return ()
            else do putStrLn "Enter an existing fan: "
                    name <- getLine
                    putStrLn filmsByFan name  <<< **error here**
                    main

我遇到的问题是当超过 2 个函数应用于 IO if 语句时,当用户输入分配“名称”时,它似乎没有注册,因此名称中的其余代码

我的问题是:有没有办法让用户根据他们选择的内容来选择要执行的功能并执行适当的功能...?

提前致谢!

编辑:

我希望代码如何执行的示例:

Main
which function would you like to execute...1,2,3,4,5,6?
user enters: 1
displayFilms will execute.

IF USER ENTERS 4

user enters: 4
Enter an existing fan:
user enters: Liz"
execute filmsByFan

【问题讨论】:

  • 对不起,我不明白。您发布的代码有问题吗?如果是这样,请复制+粘贴完整的错误消息。或者,您是否对未向我们展示的其他代码有问题?在这种情况下,请将该代码复制并粘贴到您的问题中(以及完整的错误消息)。 我不明白你所说的“超过 2 个函数应用于 IO if 语句”是什么意思,我不想猜测。
  • 问题似乎是输入例如"3" 将使两个“菜单项”都出现。解决方案当然是使用== 而不是/=,或者case..of 表达式。也可以使用when 函数。
  • main :: IO () 是上面粘贴的代码。我得到的错误消息是: ExampleSolution.hs:167:12: parse error on input `do' 基本上我想做的是,在执行 main 时,用户可以通过键入 1、2 来选择要运行的函数, 3, 4...如果选择 1 则运行 displayFilms 函数,并提示用户输入适当的参数以满足该功能,然后执行 displayFilms;现在如果选择 4,它将运行filmsByFan,它会提示用户输入与数据库对应的现有粉丝。查看编辑
  • 顺便说一下,在这里您可能还希望将电影列表数据库作为参数传递给 main (main myFilmListArgument),并在交互函数中使用它,而不是在全局电影中使用列出值,因此您可以将更新后的版本传递回循环中。
  • 主 IO,只是代码的一部分,只有选择 1 和 4 有效,只要它允许用户区分运行哪个函数,我就可以围绕它构建,因此最终完成所有 6 个功能的主要 IO。

标签: haskell if-statement input io output


【解决方案1】:

您可以将所有函数放在一个表中,然后使用lookup 选择要运行的函数。

table = [(1, addFilm)
        ,(2, displayAllFilms)
        ,(3, filmsByYear)
        ,(4, filmsByFan)
    ]

我将您的 filmsByFan 重命名为 filmsByFan'(素数),所以我可以添加一个层来提示输入密钥并调用您的 orig 函数:

filmsByFan = do putStr "Enter Fan"
                f <- getLine
                print $ filmsByFan' f               
filmsByFan' f = map title $ filter (elem f . fans) testDatabase
main :: IO ()
main = do putStrLn "What function would you like to execute? 1. addFilm / 2.displayAllFilms / 3. filmsByYear / 4. filmsByFan / 5. filmsByActor Period / 6. becomeFan: "
          str <- getLine
          let n = (read str)::Int
              cmd = lookup n table
          case cmd of
            Just doIt -> doIt
            Nothing   -> do print "sorry"
                            main

【讨论】:

    【解决方案2】:

    你说你得到的错误信息是

    ExampleSolution.hs:167:12: parse error on input `do'
    

    你没有说哪一行是第 167 行。

    您似乎在混合使用空格和制表符。这可能是问题的原因。将源代码中的所有制表符替换为空格。

    编辑:我说您似乎混合了空格和制表符,因为您问题中的源代码混合了空格和制表符。例如有错误的行的缩进以制表符结尾,而它上面的行中的缩进以八个空格结尾,并且似乎没有缩进。

    这与台词一致

    name <- getLine
    putStrLn filmsByFan name
    

    其实是

    name <- getLine
            putStrLn filmsByFan name
    

    并被解释为

    name <- getLine putStrLn filmsByFan name
    

    这将导致您现在报告的错误:

    ExampleSolution.hs:174:61: Not in scope: `name'
    

    因为name 定义在&lt;- 的左侧,因此不能在右侧使用:它只能在块中的后续行中使用。

    检查您的编辑器在保存文件时没有将空格转换为制表符,这与您的意愿相反。或者,确保它使用 8 个空格宽的制表符(我猜您可能正在使用 4 个空格宽的制表符)。

    n.b.您可能打算阅读这些行

    name <- getLine
    putStrLn (filmsByFan name)
    

    【讨论】:

    • 抱歉,错误代码是:ExampleSolution.hs:174:61: Not in scope: `name' - 我复制并粘贴了错误的代码。这对应于这一行:putStrLnfilmsByFan 名称,我也没有标记任何缩进都已适当间隔。
    • 我已经编辑了显示错误所在的原始帖子。见编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 2016-11-09
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2016-10-01
    • 1970-01-01
    相关资源
    最近更新 更多