有效的应用程序编程中效果概念的含义是什么?
例如,下面表达式的哪些部分是效果?
[(+1)] <*> [2,3]
Just (+1) <*> Nothing
答案 0 :(得分:7)
在FP世界中,效果是任何类型的构造函数,例如Maybe
,[]
,IO
等。效果不应与副作用混淆。直觉上,效果是您计算的价值的附加属性。 Maybe Int
表示您的计划会计算出有失败影响的Int
,或[Int]
表示您的计划会计算Int
,但会产生非确定性效果(非确定性)结果在此建模为可能结果列表。)
从这里开始,我们有术语 applicative effects 和 monadic effects ,这意味着所述效果包含Applicative
和Monad
个实例
我无法找到任何权威信息,这正是我根据自己的经验收集到的信息。
答案 1 :(得分:6)
很多混淆是由不幸的名字选择造成的,这在Haskell中很常见(想想&#34; return
&#34;更好地命名为&#34; emit
&# 34。)
pure x
不纯,x
是纯粹的,pure
只是注入。它是envisioned to be used in pure f <*> a <*> b <*> ...
模式,让我们有效地应用纯函数f
。
[]
applicative让我们&#34;非确定性地&#34;将(<*>
,而非$
) 非确定性值(在您的示例中不是两个值)应用于非 - 确定功能; 非决定论是效果。
在list applicative中,[(+1), (+2)]
是一个非确定性函数,可能会将值递增1,也可能会将其递增2. [3,4,5]
是一个非确定性值,其可能值列出。正如我们通常将(+1)
和3
应用为(+1) $ 3
一样,我们也可以将非确定性值非确定性应用为{{1} }或[(+1)] <*> [3]
。
使用[(+1),(+2)] <*> [3,4,5]
失败的可能性就是效果。
答案 2 :(得分:5)
我们可以说f a
类型的效果是pure x
x :: a
所不能写的任何内容。
在[]
申请中pure x = [x]
,所以[(+1)] = pure (+1)
可能不应被视为效果。同样在Maybe
应用中pure = Just
,所以Just (+1)
不起作用。
在您的相应示例中留下[2,3]
和Nothing
作为效果。从[]
表示非确定性计算的角度来看,这具有直观意义:[2,3]
非确定性地选择2到3之间;以及Maybe
表示计算失败的观点:Nothing
无法进行计算。
我使用的定义是一种效果(也许是“副作用”会是一个更好的词)是无法写的,因为pure x
只是让你的问题变得精确,而不是代表任何形式的共识或标准定义。 Will Ness's answer提供了一个不同的视角,pure
从纯值生成一个有效的计算,它有一个很好的数学环 - 即这个定义可能更容易在精确设置中使用。
答案 3 :(得分:4)
有效的应用程序编程可以被认为是定期进行无效计算并向其添加效果。这些实现为Applicative
个实例。因此,虽然Int
是常规值,但A Int
是Int
,其效果为A
,A
是Applicative
的实例。< / p>
考虑这个表达式:
x + y :: Int
这个表达无效;它只涉及规则的,简单的价值观,可以这么说。但我们也可以有效添加。
一个影响是失败;计算可能失败或成功。如果失败,则停止计算。这只是Maybe
类型。
Just (+1) <*> Nothing :: Maybe Int
除了常规值,您只需将数字加在一起即可。但是现在,我们添加了可能失败的。所以我们必须将数字加在一起,前提是计算没有失败。我们在这个表达式中看到计算将失败,因为第二个操作数是Nothing
。
如果您的计算失败的原因不仅仅是一个原因,您可能希望有错误消息来报告发生的失败类型。然后,您可以使用错误效果,该效果可能表示为Either String
(String
是错误消息的类型)。此Applicative
的实施与Maybe
Applicative
的行为类似。
效果的另一个例子是解析。解析可以通过使用构造函数并使其有效来实现。假设你想用加法和乘法实现一个简单的算术语言。这可能是您的抽象语法树(AST):
data Exp = Num Int | Var String
data AST = Add Exp Exp | Multiply Exp Exp
只需使用这些构造函数即可构建AST。但问题是你还需要实际解析文本,那么解析的行为呢?如何跟踪您消耗了多少文本?如果解析失败会怎么样,因为文本不符合你的语法?好吧,在像Parsec
这样的库中,这就是解析效果。您使用了一些Parse
数据类型(即Applicative
的实例)并将构造函数提升到有效的Parse AST
世界。现在,您可以在实际解析文本时构造AST,因为解析是添加到AST构造的效果。
请注意,Parse
类型比Maybe
和Either String
实例更复杂;解析器具有跟踪状态的效果,例如已经消耗了多少输入文本,以及失败的解析,这将产生错误消息。 Applicative
效果可以像这样组合在一起。