根据 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 ]
.
我是 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 ]
.