Haskell-将变量传递给子函数

Haskell-将变量传递给子函数,haskell,Haskell,我有一个功能main,它有一个子功能菜单。在main中,我加载一个文件,要求用户输入他们的姓名,然后调用menu显示菜单。菜单中的每个操作完成后,我将再次调用菜单,直到满足退出条件 我无法将加载到main中的文件传递到菜单中-我想对每个命令的数据库执行操作 这是到目前为止我的代码(我删去了一些不相关的部分): 我认为,如果我没有指定像menu::Database->IO()这样的行,它将接受任何参数,而不关心它们的类型 有什么建议吗 编辑: 愚蠢的错误,我只是忘记了在案例陈述之后再次调用菜单时传

我有一个功能
main
,它有一个子功能
菜单
。在
main
中,我加载一个文件,要求用户输入他们的姓名,然后调用
menu
显示菜单。菜单中的每个操作完成后,我将再次调用
菜单
,直到满足退出条件

我无法将加载到
main
中的文件传递到
菜单中
-我想对每个命令的数据库执行操作

这是到目前为止我的代码(我删去了一些不相关的部分):

我认为,如果我没有指定像
menu::Database->IO()
这样的行,它将接受任何参数,而不关心它们的类型

有什么建议吗

编辑:
愚蠢的错误,我只是忘记了在案例陈述之后再次调用菜单时传递数据库

首先,不指定类型并不意味着函数将接受任何类型这意味着将推断类型

您得到该特定类型错误的原因是,在
菜单
do
块的末尾,您写入了
菜单
,这是一个函数,而不是类型为
IO
的值。我不太清楚你为什么这么做。如果要创建无限循环,应将最后一次调用更改为
菜单db
,而不是返回未应用的函数。如果你不想要一个无限循环,我根本不明白你为什么要在最后使用
菜单

我认为,如果我没有指定像
menu::Database->IO()
这样的行,它将接受任何参数,而不关心它们的类型

那不是真的,在你的例子中,
菜单
确实有类型
数据库->IO()
,所以在
前面的最后一行,你需要给它一个
数据库
,以获得
IO()
-可能是
数据库
(如
菜单数据库
),但可能以后,您将开始修改数据库,然后可以传入新数据库。Haskell不仅仅是查看范围内的内容,以找到类型为
数据库
的合适值

如果数据库确实已修复,则无需将其传入,您可以使用以下方法:

main = do contents <- readFile "myfile.txt"
       let finalDatabase = (read contents :: [Film])
       putStr "Please enter your name: "
       name <- getLine
       menu
       where menu = do putStrLn "Please select an option:"
                       putStrLn "1: Display all films"
                       putStr "Choice: "
                       choice <- getLine
                       case choice of {
                           "1" -> displayAll finalDatabase -- instead of db
                       }
                       menu

另一个选择是使用隐式参数,但我猜目前这有点太高级了

感谢您解释推断类型。是的,我在再次调用菜单时错过了参数。在调用
menu db
Nice answer之前,我将最终更改它以检查条件,谢谢。是的,现在正在做一个介绍性的haskell/函数式编程单元,所以隐式参数有点高级,你是对的!
ERROR file:.\films.hs:152 - Type error in function binding
*** Term           : menu
*** Type           : [([Char],[[Char]],Int,[[Char]])] -> IO a
*** Does not match : IO a
main = do contents <- readFile "myfile.txt"
       let finalDatabase = (read contents :: [Film])
       putStr "Please enter your name: "
       name <- getLine
       menu
       where menu = do putStrLn "Please select an option:"
                       putStrLn "1: Display all films"
                       putStr "Choice: "
                       choice <- getLine
                       case choice of {
                           "1" -> displayAll finalDatabase -- instead of db
                       }
                       menu
      <same as before>
      menu finalDatabase
      where menu db = do putStrLn "Please select an option:"
                         putStrLn "1: Display all films"
                         putStr "Choice: "
                         choice <- getLine
                         newDb <- doSomethingWithDatabaseDependingOnChoice choice db
                         menu newDb