-1

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

f x

  | x < 10 = g x

  | x < 15 = h x

  | otherwise = m x

这只是一个简化,我实际上有一个不同的程序。情况不同,我只是想像其他编程语言一样拥有多个 if 语句。所以在这个例子中,如果 x < 10 那么做一些事情,如果 x < 15 也做这个。

4

2 回答 2

8

在纯函数式编程中,我们不像在命令式编程中那样执行语句。没有“做这个,然后做那个”的概念。相反,我们主要编写将一些参数作为输入并返回一些输出的函数。

如果我们确实想与世界交互,而不仅仅是计算返回值怎么办?好吧,在这种特殊情况下,我们求助于 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 中,然后接触任何命令式编程语言,他们可能会问这样的想法:“我如何使用状态单子?”。即使您可以在 -say- Java 中使用 state monad,那也是愚蠢的,因为使用可变变量会更加自然。再次,编程试图将他们以前的方法硬塞进新的语言/范式中,忽略新特性,并产生单一的代码。

于 2019-03-03T12:48:16.703 回答
4

“例如 f 5 执行 gx 然后还执行 h x”

并返回什么?我们必须返回一些,这就是 Haskell 的e-valu-ation进行的方式。

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

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

此列表将包含其|(列表理解保护)右侧的表达式评估为的所有结果True++将两个列表加在一起。True简单地计算为True所以可以省略:[ m x ].

于 2019-03-03T12:52:38.763 回答