You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Control.Wire.Unsafe.Event需维护哪些不变量?Netwire开发疑问

Answers to Your Netwire Event Questions

Let's break down your questions one by one, drawing on Netwire's design principles and practical best practices:

1. Why is Control.Wire.Unsafe.Event marked as unsafe?

Netwire's Event type has a non-negotiable semantic rule: an event can fire at most once per time step (i.e., per single call to stepWire with a given session state). The Unsafe.Event module exposes raw constructors and utilities that let you bypass this rule entirely.

For example, if you manually combine two Event values like Event "foo" <> Event "bar" to create a multi-event value for the same time step, you're breaking the core invariant that keeps Netwire's time-aware logic predictable. This can lead to bugs like duplicate message processing, broken state transitions, or race conditions in your network-driven program. The "unsafe" label is a clear warning: using these tools shifts the responsibility of maintaining Event's correctness from the type system to you.

2. What invariants must you maintain to use it safely?

When working with Unsafe.Event, you need to enforce these critical rules to avoid breaking your program's behavior:

  • Single event per time step: Never create an Event value that contains more than one occurrence for the same time step. This includes avoiding direct combinations of multiple Event constructors unless you're certain they belong to distinct steps.
  • Align events with wire time: Events must only be generated in sync with the current time step of your wire session. Don't create events referencing past or future steps unless your wire's logic explicitly handles this edge case (and even then, proceed with extreme caution).
  • No events from inhibited wires: If your wire is in an inhibited state (Inhibited e), it should never produce an event. Inhibition means the wire is inactive in the current step—emitting an event would contradict that state.
  • Preserve purity: Ensure event creation doesn't introduce unintended side effects that break referential transparency. Netwire relies on pure wire functions for consistent state management.

3. Implementing mapMaybeE for filtering network events

You don't need unsafe tools to build this filter wire—you can safely implement it using standard Netwire combinators and Event's built-in semantics. Here are two clean, safe approaches:

Basic Pattern-Matching Implementation

import Control.Wire
import Control.Wire.Event (Event(..))

mapMaybeE :: Monad m => (a -> Maybe b) -> Wire s e m (Event a) (Event b)
mapMaybeE f = arr $ \event -> case event of
    NoEvent -> NoEvent
    Event a -> case f a of
        Just b  -> Event b
        Nothing -> NoEvent

Concise Version Using Event's Monad Instance

Since Event acts as a Monad that only propagates events when the result is Just, you can write this even more succinctly:

mapMaybeE :: Monad m => (a -> Maybe b) -> Wire s e m (Event a) (Event b)
mapMaybeE f = arr $ \event -> event >>= \a -> maybe NoEvent Event (f a)

Both implementations are safe because they preserve Event's core invariant: if the input event is valid (one occurrence per step), the output will also be valid. They only filter or transform existing events—never create invalid multi-event values.

内容的提问来源于stack exchange,提问作者Echo Nolan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:36:33