作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想创建一个 Behavior t a
来自 IO a
,其预期语义是每次行为为 sample
时都会运行 IO 操作d:
{- language FlexibleContexts #-}
import Reflex.Dom
import Control.Monad.Trans
onDemand :: (MonadWidget t m, MonadIO (PullM t)) => IO a -> m (Behavior t a)
measurement
来做到这一点在
pull
:
onDemand measure = return $ pull (liftIO measure)
Behavior
在初始
measure
之后永远不会改变更换。
Behavior
改变“足够频繁”,然后创建一个虚假的依赖:
import Data.Time.Clock as Time
hold_ :: (MonadHold t m, Reflex t) => Event t a -> m (Behavior t ())
hold_ = hold () . (() <$)
onDemand :: (MonadWidget t m, MonadIO (PullM t)) => IO a -> m (Behavior t a)
onDemand measure = do
now <- liftIO Time.getCurrentTime
tick <- hold_ =<< tickLossy (1/1200) now
return $ pull $ do
_ <- sample tick
liftIO measure
Behavior
s 无论如何只能按需采样,这不是必需的。
Behavior
的正确方法是什么?对于一个连续的、随时可观察的现象?
最佳答案
在 Spider
中执行此操作看起来不可能。 Internal
提前推理。
在 Spider
Reflex
的实现, 可能的 Behavior
之一s 是拉取值。
data Behavior a
= BehaviorHold !(Hold a)
| BehaviorConst !a
| BehaviorPull !(Pull a)
Pull
ed value 包含如何在需要时计算该值,
pullCompute
,以及一个缓存值以避免不必要的重新计算,
pullValue
.
data Pull a
= Pull { pullValue :: !(IORef (Maybe (PullSubscribed a)))
, pullCompute :: !(BehaviorM a)
}
BehaviorM
的丑陋环境,
liftIO
解除
IO
计算方式很明显,它在
BehaviorM
时运行需要采样。在
Pull
,您的行为会被观察一次,但不会被重新观察,因为缓存的值没有失效。
PullSubscribed a
由值
a
组成,如果该值无效,则需要使其无效的其他值的列表,以及一些无聊的内存管理内容。
data PullSubscribed a
= PullSubscribed { pullSubscribedValue :: !a
, pullSubscribedInvalidators :: !(IORef [Weak Invalidator])
-- ... boring memory stuff
}
Invalidator
是一个量化的
Pull
这足以让内存引用递归地读取无效器以使缓存值无效并将缓存值写入
Nothing
。 .
BehaviorM
失效.执行时,环境传递给
BehaviorM
有自己的无效器的副本,由
BehaviorM
的依赖项使用当他们自己变得无效时使其无效。
readBehaviorTracked
的内部实现行为自己的无效器(
wi
)似乎永远不会出现在采样时无效的订阅者列表中(
invsRef
)。
a <- liftIO $ runReaderT (unBehaviorM $ pullCompute p) $ Just (wi, parentsRef)
invsRef <- liftIO . newIORef . maybeToList =<< askInvalidator
-- ...
let subscribed = PullSubscribed
{ pullSubscribedValue = a
, pullSubscribedInvalidators = invsRef
-- ...
}
Behavior
的方法它将涉及
MonadFix (PullM t)
通过修复
pull
实现实例或相互递归和
sample
:
onDemand :: (Reflex t, MonadIO (PullM t)) => IO a -> Behavior t a
onDemand read = b
where
b = pull go
go = do
sample b
liftIO read
Reflex
尝试这个的环境,但我不认为结果会很漂亮。
关于haskell - 为持续可测量的现象创建行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35957463/
我是一名优秀的程序员,十分优秀!