当执行所规定的输入输出动作的someFun <$> (a :: IO ()) <$> (b :: IO ())
时,在执行a
和b
的动作命令? 也就是说,我就可以在计算a
被执行之前b
是什么?
对于GHC,我可以看到IO使用国家实现,也看到这里 ,这是一个应用型的实例,但无法找到实际的实例声明的来源。 通过国家正在实施表明,不同的IO效果需要是连续的,但并不一定定义它们的排序。
在GHCI玩耍似乎Appliative保留效果的顺序,但就是一些普遍的担保,或GHC具体? 我会感兴趣的细节。
import System.Time
import Control.Concurrent
import Data.Traversable
let prec (TOD a b) = b
fmap (map prec) (sequenceA $ replicate 5 (threadDelay 1000 >> getClockTime))
[641934000000,642934000000,643934000000,644934000000,645934000000]
谢谢!
这当然是确定性的 ,是的。 它总是做同样的事情对任何特定的实例。 然而,有没有内在的理由选择左向右过从右到左为效果的顺序。
然而,从对文档Applicative
:
如果f
也是一个Monad
,它应满足pure
= return
和(<*>)
= ap
(这意味着pure
和<*>
满足适用函子法律)。
的定义ap
是这样的,从Control.Monad
:
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap = liftM2 id
而liftM2
在明显的方式定义:
liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
这意味着,对于任何仿函数是一个Monad
,也是一个Applicative
,预期(由规范,因为这不能在代码执行),即Applicative
将工作左到右,使的do
在块liftM2
做同样的事情作为liftA2 fxy = f <$> x <*> y
。
由于上述,即使是Applicative
没有相应的情况下Monad
,按约定的效应通常下令左到右为好。
更广泛地说,因为结构Applicative
计算必然是独立的“效果”,通常可以分析独立的程序如何的含义Applicative
效应测序。 例如,如果用于实例[]
改变为序列从右到左,使用它会给相同的结果,只是以不同的顺序列表中的元件的任何代码。
是的,顺序由单子-应用型对应预定义的。 这是很容易地看到: (*>)
组合子需要对应于(>>)
组合子中表现良好的Applicative
实例单子,它的定义是:
a *> b = liftA2 (const id) a b
换句话说,如果b
是之前执行a
中, Applicative
的实例是不良道德的。
编辑:作为一个方面说明:这是没有明确规定的任何地方,但你可以找到许多其他类似的信件像liftM2
= liftA2
等。
对于IO应用型,这是毋庸置疑的事实。 但检查出异步包为一个应用型的示例,其中在f <$> a <*> b
的影响a
和b
发生平行。