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