variables - 使用 Haskell 从 if 语句获取输入并传递变量

标签 variables haskell if-statement io

这是我正在处理的代码的简化版本。

main :: IO ()
main = do
     args <- getArgs
     if null args
       then putStr "> " ; userInput <- getLine
       else userInput <- readFile $ head args

     let conclusion = userInput

如果没有 do 符号,这将无法工作,当我使用它时,变量不会传递到下面的结论,以及我试图用它来创建一种提示,只会让它发疯。

有什么我忘记添加的东西吗?

最佳答案

这里有一些问题。首先,您需要在 thenelse 之后包含 do:

if null args
  then do putStr "> " ; userInput <- getLine
  else do userInput <- readFile $ head args
do 表示法中的

if 与其他地方的 if 相同;你必须在 thenelse 之后放置一个 expression,而不是语句,并且你需要 do 来转换一堆语句变成一个表达式。不过,这仍然不是很有效; do block 中的最后一个语句必须是一个表达式,但这里有一个绑定(bind)。毕竟,每个语句都必须有一个结果值,但绑定(bind)没有。

第二个问题是,正如您所观察到的,这引入了一个新的作用域,因此您无法访问从外部绑定(bind)的变量。如果您考虑一下,这是有道理的;毕竟,您可以将变量绑定(bind)在一侧而不是另一侧。解决方案是将绑定(bind)移到if:

main :: IO ()
main = do
     args <- getArgs
     userInput <- if null args
       then do putStr "> " ; getLine
       else readFile $ head args

     let conclusion = userInput

因此,我们绑定(bind)到 userInput 的操作仍然根据 null args 的结果进行计算,但我们将变量绑定(bind)在条件之外。

请注意,这次我没有将do 添加到else 分支;这不是必需的,因为那里只有一个表达式。 (它仍然有效,但在不需要时使用 do 是不合常理的。)

除非您在 let conclusion = userInput 行之后添加一些内容,否则此代码仍然无法运行(因为,正如我所说,do block 必须以表达式结尾) ,但大概您已经有了代码。

作为附加说明,您应该避免使用像headtail 这样的函数; head 是一个偏函数(不是为每个参数都定义的——head [] 会产生错误),这些通常被认为是不合常理的。您应该改用模式匹配,如下所示:

userInput <- case args of
  [] -> do putStr "> " ; getLine
  fileName:_ -> readFile fileName

这就像定义函数时使用的模式匹配,但针对的是单个值而不是任意数量的参数。

关于variables - 使用 Haskell 从 if 语句获取输入并传递变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9216940/

相关文章:

objective-c - 在 Objective-C 中,未赋值的 int 变量是 nil 吗?

variables - 如何使用 (ns ( :require :refer))

haskell - 计算 n 元笛卡尔积

haskell - 如何用 Either 数据类型编写 writeFile?

java - 了解 Java 中的 If 语句

Excel VBA : "For" and "If" statement on a single line?

PHP 使用 $i 进行计数

c++ - 如何将位从一个变量复制到另一个变量?

haskell - 为什么在 do block 中需要 let 关键字?

java - 如何检查应用程序是否在 Android 上运行?