根据 Haskell 中的布尔条件执行多个语句

Execute multiple statements based on boolean conditions in Haskell

我是 Haskell 的新手 我正在尝试在几个布尔值都为真时执行多个语句。我尝试使用守卫,但它只执行第一个为真的语句,然后停止。我希望它执行所有正确的,例如 f 5 执行 g x 然后还执行 h x。我尝试使用 if 语句,但我做不到。

f x

  | x < 10 = g x

  | x < 15 = h x

  | otherwise = m x

这只是一个简化,实际上我有一个不同的程序。情况不同,我只是想像其他编程语言一样使用多个 if 语句。因此,在此示例中,如果 x < 10 则执行某项操作,如果 x < 15 也执行此操作。

在纯函数式编程中,我们不像在命令式编程中那样执行语句。没有 "do this, then do that" 的概念。相反,我们主要编写函数,将一些参数作为输入,return 一些输出。

如果我们确实想与世界互动,而不是仅仅计算一个 return 值怎么办?那么,在这种特定情况下,我们求助于 IO monad。请注意,这不是我们经常做的事情——我们更愿意尽可能避免使用 IO monad,以便保持大部分计算的纯净。

这是一个例子:

f :: Int -> IO ()
f x = do
   putStrLn "hello"
   if x > 15
   then putStrLn "> 15"
   else putStrLn "not > 15"
   if x > 10
   then putStrLn "> 10"
   else putStrLn "not > 10"

如果您是初学者,我建议您在使用 IO monad 之前学习 Haskell 基础知识。在任何地方使用 IO monad 都会导致代码非常单一。

大多数学习 FP 的命令式程序员都试图将他们以前的习惯硬塞进 FP 语言中——这很常见。然而,带有副作用和可变变量的编程并不能很好地应对 FP。一个人逐渐需要停止根据有效的陈述来思考,而是重新布线一个人的大脑,以便根据价值观和(通常是递归的)定义来思考。

注意FP在这方面并不特殊。如果一个人先学习纯 FP,比如 Haskell,然后再接触任何命令式编程语言,他们可能会问 "how do I use a state monad?" 这样的想法。即使您可以在 -say- Java 中使用状态 monad,那也是愚蠢的,因为使用可变变量会自然得多。同样,编程试图将他们以前的方法硬塞进新的 language/paradigm,忽略新功能,并生成不合常理的代码。

"for example f 5 executing g x and then also executing h x"

和 return 什么?我们必须 return 一些 ,这就是 Haskell 的 e-valu-ation 的方式。

如果您想要这两个语句的值,可以将它们放在一个列表中来组合它们:

f x = [ g x | x < 10 ] ++ [ h x | x < 15 ] ++ [ m x | True ]

此列表将包含其 |(列表理解守卫)右侧的表达式求值为 True 的所有结果。 ++ 将两个列表合二为一。 True 平凡地评估为 True 因此可以省略:[ m x ].