简体   繁体   English

什么是应用效果?

[英]What are applicative effects?

What is the meaning of the concept of effect in effectful applicative programming ?有效应用程序编程效果的概念是什么意思?

For example, which parts of expressions below are the effects ?例如,下面表达式的哪些部分是效果

[(+1)] <*> [2,3]
Just (+1) <*> Nothing

In the FP world, an effect is any type constructor such as Maybe , [] , IO , etc. Effects are not to be confused with side-effects.在 FP 世界中,效果是任何类型的构造函数,例如Maybe[]IO等。不要将效果与副作用混淆。 Intuitively, an effect is an additional property of the value you're computing.直观地说,效果是您正在计算的值的附加属性。 Maybe Int means that your program calculates an Int with a failure effect, or [Int] means that your program calculates an Int but with a non-deterministic effect (a non-deterministic result is here modeled as a list of possible results). Maybe Int意味着您的程序计算了一个具有失败影响的Int ,或者[Int]意味着您的程序计算了一个Int但具有非确定性影响(非确定性结果在这里建模为可能结果的列表)。

Going from here, we have the terms applicative effects and monadic effects , which mean that the said effects have Applicative and Monad instances.从这里开始,我们有术语applicative effectsmonadic effects ,这意味着所述效果具有ApplicativeMonad实例。

I can't find any authoritative information for this, it's just what I have gleaned in my experience.我找不到任何权威信息,这只是我在我的经验中收集到的。

Much confusion was caused by the unfortunate choice of names, as is quite common in Haskell (think " return ", much better named " emit ").不幸的名字选择引起了很多混乱,这在 Haskell 中很常见(想想“ return ”,更好地命名为“ emit ”)。

pure x is not pure, it is x that is pure, pure is just inject . pure x不纯, pure x是纯的, pure只是注入 It was envisioned to be used in pure f <*> a <*> b <*> ... pattern, letting us effectfully apply a pure function f .它被设想用于pure f <*> a <*> b <*> ...模式,让我们有效地应用纯函数f (1) (1)

[] applicative (2) lets us "non-deterministically" apply ( <*> , not $ ) a non-deterministic value (not two values , in your example) to a non-deterministic function; []应用性(2)让我们“非确定性”应用<*>而不是$确定性值(而不是两个值,在你的例子),以非确定性函数; the non-determinism is the effect.非确定性就是效果。 (3) (3)

In list applicative, [(+1), (+2)] is a non-deterministic function that might increment a value by 1, and also might increment it by 2. [3,4,5] is a non-deterministic value whose possible values are listed.在列表应用中, [(+1), (+2)]是一个非确定性函数,它可能将一个值增加 1,也可能将它增加 2。 [3,4,5]是一个非确定性值列出了其可能的值。 Just as we apply normal entities (+1) and 3 normally, as (+1) $ 3 , so can we apply non-deterministic values non-deterministically , as [(+1)] <*> [3] or [(+1),(+2)] <*> [3,4,5] .正如我们应用正常的实体(+1)3通常,如(+1) $ 3 ,所以可以我们应用非确定性值的非确定性,如[(+1)] <*> [3][(+1),(+2)] <*> [3,4,5]

And with Maybe the possibility of failure is the effect.Maybe失败可能性是效果。


(1) as the paper says, in Introduction: "we collect the values of some effectful computations, which we then use as the arguments to a pure function (:) " (1)正如论文在介绍中所说: “我们收集一些有效计算的值,然后将其用作纯函数的参数(:)

(2) [] by itself is not an applicative, ([], pure :: a -> [a], (<*>) :: [a -> b] -> [a] -> [b]) is an applicative, given some (lawful) implementations of pure and (<*>) . (2) []本身不是一个应用, ([], pure :: a -> [a], (<*>) :: [a -> b] -> [a] -> [b])考虑到pure(<*>)一些(合法)实现,是一种应用。

(3) x is pure (as in, "Haskell is pure"); (3) x是纯的(如“Haskell 是纯的”); pure x stands for an effectful computation producing x without actually having any additional effect. pure x代表有效计算产生x而实际上没有任何附加效果。 "without an effect" refers to the law of pure x *> u == u ie pure x doesn't add any effect into the combined computation on top of u 's contribution. “没有影响”指的是pure x *> u == u定律,即pure x不会在u贡献之上的组合计算中添加任何影响。 But the possibility of effect is there.但效果的可能性是存在的。

pure 7 :: IO Int is certainly not the pure (as in, "Haskell is pure") value 7 , it is the pure value 7 in the effectful context ( IO ). pure 7 :: IO Int当然不是纯(如“Haskell 是纯的”)值7 ,它是有效上下文( IO )中的纯值7 Even if it does no effectful action in that context, it's still in that context ( IO ).即使它在那个上下文中没有采取有效的动作,它仍然那个上下文中( IO )。

on the other hand, and unrelated to the purpose of pure , of course any Haskell value is pure and referentially transparent.另一方面,与pure的目的无关,当然任何Haskell 值都是纯的并且引用透明。 getLine is a pure, referentially transparent Haskell value . getLine是一个纯粹的、引用透明的 Haskell It stands for an effectful I/O computation , getting an input line from a user and producing it as the result to be used by the next I/O computation.代表有效的 I/O计算,从用户那里获取输入行并将其作为结果供下一个 I/O 计算使用。

print 7 is a pure referentially transparent Haskell value. print 7是一个纯粹的引用透明 Haskell 值。 that's not a kind of "pure" that is meant here.这不是这里所说的一种“纯”。 [1,2] is a pure value, but seen from another angle it's a nondeterministic value with two possible pure values 1 and 2 . [1,2]是一个纯值,但从另一个角度来看,它是一个不确定值,具有两个可能的纯值12 Same for [1] . [1] It can still be interpreted as a nondeterministic value with one possible pure value, 1 .它仍然可以解释为具有一个可能的纯值1的不确定值。

[1,2] *> [10,20] = [10,20,10,20] ; [1,2] *> [10,20] = [10,20,10,20] ; [1] *> [10,20] = [10,20] . [1] *> [10,20] = [10,20] So unlike [1,2] , [1] doesn't add any nondeterminism into the nondeterministic computation described by [10,20] .因此,与[1,2]不同, [1]不会在[10,20]描述的非确定性计算中添加任何不确定性。 But it's still a nondeterministic value, it can participate in *> .但它仍然是一个不确定的值,它可以参与*> 1 can't. 1不能。 ( [1] is of course the same as pure 1 ). [1]当然与pure 1相同)。

We know a type by what kind of interactions it can participate in.我们通过它可以参与的交互类型来了解类型。

Or, as the user @bob puts it ( in the comments ), " pure x puts a pure x into an effectful context without actually performing [any] effect".或者,正如用户@bob所说的( 在评论中),“ pure x将纯x置于有效上下文中,而不实际执行 [任何] 效果”。

See also:也可以看看:

We could say that an effect of type fa is anything that can't be written as pure x where x :: a .我们可以说fa类型的效果是任何不能写成pure x其中x :: a

In the [] applicative, pure x = [x] , so [(+1)] = pure (+1) probably shouldn't be considered an effect.[]应用中, pure x = [x] ,因此[(+1)] = pure (+1)可能不应被视为效果。 Similarly in the Maybe applicative, pure = Just , so Just (+1) is not an effect.同样,在Maybe应用中, pure = Just ,所以Just (+1)不是效果。

That leaves [2,3] and Nothing as the effects in your respective examples.这将[2,3]Nothing作为您各自示例中的效果。 This makes intuitive sense from the perspective that [] denotes nondeterministic computations: [2,3] nondeterministically chooses between 2 and 3;[]表示非确定性计算的角度来看,这具有直观意义: [2,3]在 2 和 3 之间非确定性地选择; and the perspective that Maybe denotes failing computations: Nothing fails the computation.以及Maybe表示计算失败的观点: Nothing失败计算。

The definition I used that an effect (perhaps "side-effect" would be a better word) is something that can't be written as pure x is just a swing at making your question precise, and does not represent any sort of consensus or standard definition.我使用的定义是效果(也许“副作用”会是一个更好的词)不能写成pure x只是使您的问题变得精确的一种摆动,并不代表任何形式的共识或标准定义。 Will Ness's answer gives a different perspective, that pure generates an effectful computation from a pure value, which has a nice mathematical ring to it -- ie this definition would probably be easier to use in precise settings. Will Ness 的回答给出了一个不同的观点, pure从一个纯值生成一个有效的计算,它有一个很好的数学环 - 即这个定义可能更容易在精确设置中使用。

Effectful applicative programming can be thought of as taking regular non-effectful computations and adding effects to them.有效的应用程序编程可以被认为是进行常规的无效计算并为其添加效果 These are implemented as Applicative instances.这些被实现为Applicative实例。 So while Int is a regular value, A Int is an Int with some effect A , and A is an instance of Applicative .因此,虽然Int是常规值,但A Int是具有某种效果的Int A ,而AApplicative的实例。

Consider this expression:考虑这个表达式:

x + y :: Int

This expression is not effectful;这个表达是无效的; it only deals with regular, plain values, so to speak.可以这么说,它只处理常规的、简单的值。 But we can also have effectful addition .但是我们也可以有有效的加法

One effect is failure ;一种影响是失败 the computation may fail or succeed.计算可能失败或成功。 If it fails, then the computation is stopped.如果失败,则停止计算。 This is simply the Maybe type.这只是Maybe类型。

Just (+1) <*> Nothing :: Maybe Int

In addition with regular values, you just add the numbers together.除了常规值之外,您只需将数字相加即可。 But now, we have addition that might fail .但是现在,我们有可能会失败的加法。 So we have to add the numbers together provided that the computation has not failed .所以我们必须把这些数字加在一起,前提是计算没有失败 We see in this expression that the computation will fail, since the second operand is Nothing .我们在这个表达式中看到计算将失败,因为第二个操作数是Nothing

If your computations can fail for more than simply one reason, you might want to have error messages that report the kind of failure that happened.如果您的计算失败的原因不止一个,您可能需要错误消息来报告所发生的失败类型。 Then you may use an error effect, which might be represented as something like Either String ( String is the type of the error message).然后你可以使用一个错误效果,它可能表示为类似Either StringString是错误消息的类型)。 The implementation of this Applicative behaves similarly to the Maybe Applicative .Applicative的实现与Maybe Applicative行为类似。

Another example of an effect is parsing.效果的另一个例子是解析。 Parsing can be implemented by just using constructors and making them effectful.只需使用构造函数并使其有效就可以实现解析。 Say you want to implement a simple arithmetic language with addition and multiplication.假设您想实现一种带有加法和乘法的简单算术语言。 This could be your abstract syntax tree (AST):这可能是您的抽象语法树 (AST):

data Exp = Num Int | Var String
data AST = Add Exp Exp | Multiply Exp Exp

You build up the AST by simply using these constructors.您只需使用这些构造函数即可构建 AST。 But the problem is that you also need to actually parse the text, so what about the act of parsing?但问题是你还需要真正解析文本,那么解析的行为呢? What about keeping track of how much of the text you have consumed?如何跟踪您已阅读了多少文本? What if the parsing fails , because the text did not conform to your grammar?如果解析失败,因为文本不符合您的语法怎么办? Well, in libraries like Parsec , that is the parsing effect .好吧,在像Parsec这样的库中,这就是解析效果 You use some Parse data type (that is an instance of Applicative ) and lift the constructors into the effectful Parse AST world.您使用一些Parse数据类型(即Applicative的实例)并将构造函数提升到有效的Parse AST世界中。 Now, you can construct the AST while actually parsing the text, because the parsing is an effect added to the construction of the AST.现在,您可以在实际解析文本的同时构建 AST,因为解析是添加到 AST 构建中的效果。

Notice that the Parse type was more complicated than both the Maybe and Either String instances;请注意, Parse类型比MaybeEither String实例都复杂; the parser has the effects of keeping track of state like how much of the input text that has been consumed, and a failed parse, which would yield an error message.解析器具有跟踪状态的作用,例如已经消耗了多少输入文本,以及解析失败,这会产生错误消息。 Applicative effects can be composed together like this. Applicative效果可以像这样组合在一起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM