问题描述
我一次又一次地读到有效这个词,但我仍然无法清楚地定义它的含义.我假设正确的上下文是有效的计算,但我也看到了术语有效的值)
我曾经认为有效意味着有副作用.但是在 Haskell 中没有副作用(除了某种程度上的 IO).仍然到处都是有效的计算.
然后我读到 monad 用于创建有效的计算.我可以在 State
Monad 的上下文中理解这一点.但是我没有在 Maybe
monad 中看到任何副作用.总的来说,在我看来,包装类似函数的东西的 Monad 比只包装一个值的 Monad 更容易被视为产生副作用.
说到 Applicative
函子,我更迷茫了.我总是将 applicative functors 视为一种map
具有多个参数的函数的方法.我在这里看不到任何副作用.或者有效和有效果有区别吗?
副作用 是可观察到的与其环境的交互(除了计算其结果值).在 Haskell 中,我们努力避免具有此类副作用的函数.这甚至适用于 IO
操作:当评估 IO
操作时,不会执行任何副作用,它们仅在 IO
中规定的操作时执行code> 值在 main
中执行.
然而,在处理与组合计算相关的抽象时,例如应用函子和单子,在某种程度上区分实际值和其余"是很方便的,我们通常称之为效果".特别是,如果我们有 kind * -> 的类型
,然后在 f
*f a
中,a
部分是值",而剩余"部分是效果".
我特意引用了这些术语,因为没有确切的定义(据我所知),它只是一个口语化的定义.在某些情况下,根本没有值,或者有多个值.例如,对于 Maybe
,效果"是可能没有值(并且计算被中止),对于 []
,效果"是有多个 (或零)值.对于更复杂的类型,这种区分可能更加困难.
效果"和值"之间的区别并不真正取决于抽象.Functor
、Applicative
和 Monad
只是给了我们工具我们可以用它们做什么(Functor
s 允许修改值在内部,Applicative
s 允许组合效果,而 Monad
s 允许效果依赖于先前的值).但是在 Monad
的上下文中,创建正在发生的事情的心理图会更容易一些,因为 monadic 操作可以看到"先前计算的结果值,正如
(>>=) :: m a ->(a -> m b) ->米
operator:第二个函数接收一个 a
类型的值,所以我们可以想象之前的计算有一些效果,现在我们可以用它的结果值做一些事情".>
Time and again I read the term effectful, but I am still unable to give a clear definition of what it means. I assume the correct context is effectful computations, but I've also seen the term effectful values)
I used to think that effectful means having side effects. But in Haskell there are no side-effects (except to some extent IO). Still there are effectful computations all over the place.
Then I read that monads are used to create effectful computations. I can somewhat understand this in the context of the State
Monad. But I fail to see any side-effect in the Maybe
monad. In general it seems to me, that Monads which wrap a function-like thing are easier to see as producing side-effects than Monads which just wrap a value.
When it comes to Applicative
functors I am even more lost. I always saw applicative functors as a way to map
a function with more than one argument. I cannot see any side-effect here. Or is there a difference between effectful and with effects?
A side effect is an observable interaction with its environment (apart from computing its result value). In Haskell, we try hard to avoid functions with such side effects. This even applies to IO
actions: when an IO
action is evaluated, no side effects are performed, they are executed only when the actions prescribed in the IO
value are executed within main
.
However, when working with abstractions that are related to composing computations, such as applicative functors and monads, it's convenient to somewhat distinguish between the actual value and the "rest", which we often call an "effect". In particular, if we have a type f
of kind * -> *
, then in f a
the a
part is "the value" and whatever "remains" is "the effect".
I intentionally quoted the terms, as there is no precise definition (as far as I know), it's merely a colloquial definition. In some cases there are no values at all, or multiple values. For example for Maybe
the "effect" is that there might be no value (and the computation is aborted), for []
the "effect" is that there are multiple (or zero) values. For more complex types this distinction can be even more difficult.
The distinction between "effects" and "values" doesn't really depend on the abstraction. Functor
, Applicative
and Monad
just give us tools what we can do with them (Functor
s allow to modify values inside, Applicative
s allow to combine effects and Monad
s allow effects to depend on the previous values). But in the context of Monad
s, it's somewhat easier to create a mental picture of what is going on, because a monadic action can "see" the result value of the previous computation, as witnessed by the
(>>=) :: m a -> (a -> m b) -> m b
operator: The second function receives a value of type a
, so we can imagine "the previous computation had some effect and now there is its result value with which we can do something".
这篇关于“有效"到底是什么?意思是的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2