在 PureScript 中混合协程和 Websockets

Mixing Coroutines and Websockets in PureScript

这是关于将 WebSocket 的输入和输出连接到协程的尝试。

以下函数采用 Connection 然后在收到消息时将其设置为 emit 协程值。

module Main where

import Prelude
import Control.Coroutine (emit, Producer, Consumer, await)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Control.Monad.Eff.Var (($=))
import Control.Monad.Reader.Trans (lift)
import Control.Monad.Rec.Class (forever)
import WebSocket (WEBSOCKET, Connection(..), newWebSocket, URL(..), runMessage, runMessageEvent)

wsProducer :: Connection → Producer String (Eff _) Unit
wsProducer (Connection s) = s.onmessage $= emit <<< runMessage <<< runMessageEvent

ProducerConsumer 将连接到 Main (WebSocket 连接也将在那里建立),虽然还没有写,因为函数以上甚至不会进行类型检查。

请问如何进行类型检查?它不会进行类型检查的事实可能意味着上面的代码中存在根本性的误解,如果是这样的话,对有效解决方案的代码示例进行解释将非常有帮助。

相关: 包含非常相似的代码。

该片段有几处错误。首先,这是一个有效的版本:

module Main where

import Prelude

import Control.Coroutine (Producer)
import Control.Coroutine.Aff (produce)
import Control.Monad.Aff (Aff)
import Control.Monad.Aff.AVar (AVAR)
import Control.Monad.Eff.Var (($=))

import Data.Either (Either(..))

import WebSocket (WEBSOCKET, Connection(..), runMessageEvent, runMessage)

wsProducer :: forall eff. Connection → Producer String (Aff (avar :: AVAR, ws :: WEBSOCKET | eff)) Unit
wsProducer (Connection s) =
  produce \emit ->
    s.onmessage $= emit <<< Left <<< runMessage <<< runMessageEvent
  1. 您缺少对 produce 的使用,这是将 emit 纳入范围的原因,也是您制作制作人的方式。
  2. 生产者必须使用Aff,而不是Eff
  3. emit 接受一个 Either - Left 值表示应该产生一个值,Right 表示应该关闭生产者。

看看at the docs for produce,希望你提到的误解会变得清楚!