在PureScript中混合协同程序和Websockets

时间:2016-09-25 06:07:24

标签: websocket purescript

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

以下函数需要Connection,然后在收到邮件时将其设置为emit一个Coroutine值。

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连接),但由于功能尚未编写以上甚至没有成功。

请问怎样才能做出类型检查呢?它赢得了类型检查的事实可能意味着上面的代码存在一个基本的误解,如果是这样的话,使用工作解决方案的代码示例进行解释会非常有帮助。

相关:this answer about Halogen and WebSockets包含非常相似的代码。

1 个答案:

答案 0 :(得分:3)

该代码片段存在一些问题。首先,这是一个有效的版本:

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表示生产者应该关闭。
  4. 看看at the docs for produce,希望你提到的误解会变得清晰!