在这种情况下,如何使用EventWriter代替EventWriterT?

时间:2019-02-19 09:30:32

标签: haskell monad-transformers reflex

我想知道,有人知道我如何将splitEventWriter1重构为splitEventWriter2吗?还是有可能?

splitEventWriter1
  :: forall t w1 w2 m a s
  .  Reflex t
  => Monad m
  => Semigroup w1
  => Semigroup w2
  => (w1 -> (w2, Maybe s))
  -> (  EventWriterT t w1 m a
     -> EventWriterT t w2 m (a, E t s)
     )
splitEventWriter1 phi cont = do
  (r, w) <- lift $ runEventWriterT cont
  let fj = First .> Just
  let (a, b) = evsIso2 $ fmap (phi.>(_1%~fj).>(_2%~fmap First)) w
  tellEvent $ a
  return (r, b)

---------------

splitEventWriter2
  :: forall t w1 w2 m1 m2 a s
  .  Reflex t
  => Monad m1
  => Monad m2
  => Semigroup w1
  => Semigroup w2
  => EventWriter t w1 m1
  => EventWriter t w2 m2
  => (w1 -> (w2, Maybe s))
  -> (  m1 a
     -> m2 (a, E t s)
     )
splitEventWriter2 = undefined

---------------

evsIso2 :: Reflex t => E t (MayFst a, MayFst b) -> (E t a, E t b)
evsIso2 e = (phi e _1, phi e _2)
  where phi e _i = (e <&> view _i) $> fmapMaybe id $> fmap getFirst

(.>) = flip (.)
($>) = flip ($)

type MayFst a = Maybe (First a)

以下是一些相关的reflex-frp文档:http://hackage.haskell.org/package/reflex-0.5/docs/Reflex-EventWriter-Base.html#t:EventWriterT

我想知道,因为似乎使用sEW1将我绑定到一个具体的monad堆栈,并要求我在使用sEW1的任何地方都使用-> EventWriterT t c m a

我的问题一方面与反射特别相关,即反射代码是否更经常使用-> EventWriterT t c m a而不是能够使用EventWriter t c m =>

另一方面,它通常与mtl样式的代码有关:在许多情况下,不能使用抽象转换器约束,并且必须不得不指定相关转换器必须位于该转换器的顶部。堆栈?

或者仅仅是我只想念一两个战略性放置的lift?还是一两个实例?

p.s。当我尝试显而易见的并且仅更改类型时,会出现类似Couldn't match type ‘m1’ with ‘EventWriterT t w1 m0’, ‘m1’ is a rigid type variable bound by ...

的错误

编辑:

除了getEvent之外,还有EventWriter的{​​{1}}类函数有意义吗?

我再次试图找出我昨天提出的问题的答案,想知道如何实现tellEvent

我注意到splitEventWriter实际上是在EventWriter的幕后实现的。

我试图将其放在一起,并编译为:https://gist.github.com/ff572e3217da1920cb32a707be16136a

有了这个,我也许可以实现具有StateT约束的splitEventWriter而不是让EventWriter污染一切。

尽管,我意识到,这不是完全相同的语义,因为事件不会被分割,只会被复制。

这本身也是值得的,因为我代码中的某些小部件只想对某些起泡事件做出反应,而又不阻止其传播。

也许除了EventWriterT之外,还具有setEvent之类的类函数,我们可以同时拥有getEventsplitEventWriter的语义。

尽管到那时我们可能只想将其命名为peekEventWriterEventStateEventMonad之类。

尽管我仍然感到困惑,但是你们中的任何人如何应对目前想传播/传播的反射事件流?您是否只返回没有EventCollector的事件?还是只在各处使用EventWriter

还是我不知道的其他方式?

如果没有,是否值得在EventWriterT中添加上述内容以减轻这一痛苦点?

0 个答案:

没有答案