2016-09-25 3 views
0

Это относится к попытке получить вход и выход WebSocket, подключенные к Coroutine.Смешивание Coroutines и Websockets в PureScript

Следующая функция принимает 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 

Producer и Consumer будут подключены в Main (соединение WebSocket будет также там), которая не была написана еще хотя, так как функция выше не будет даже typecheck.

Как это можно сделать с помощью typecheck, пожалуйста? Тот факт, что он не будет проверяться, может означать, что в приведенном выше кодексе есть фундаментальное недоразумение, если бы такое объяснение с образцом кода рабочего решения было бы очень полезно.

Связанный: this answer about Halogen and WebSockets содержит очень похожий код.

ответ

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 указывает, что производитель должен быть закрыт.

Посмотрите at the docs for produce и, надеюсь, непонятое вами упоминание станет ясным!

+0

Я задавался вопросом, следует ли мне использовать 'производить'. Я следил за документацией [purescript-coroutines] (https://pursuit.purescript.org/packages/purescript-coroutines/2.0.1), см. Функцию 'nats', которая использует' emit', но не использует ' produce'. В документах не совсем ясно, что следует использовать при каких обстоятельствах, следует ли «производить», когда есть побочные эффекты? – user4301448

+0

Этот код работает (и в основном я получаю объяснение), большое спасибо. Боюсь, мне не хватает репутации. чтобы подтвердить свой ответ, но я отметил его как принятый ответ. – user4301448

+1

Ах, да - 'produ' - это часть' -aff-coroutines', для которой вы работаете с эффектным производителем. '-coroutines' обрабатывает только общие случаи и не имеет никакого мнения о лежащей в основе монаде. Если вы отметите в документах, о которых вы говорили, 'm' остается полностью неопределенным (кроме ограничения' Monad') в 'Producer', так как он чист - это только потребитель, в который вводится« Eff », из-за к использованию 'log' там. В этом случае мы должны сделать что-то эффектное, чтобы иметь возможность сделать «Продюсер», и, следовательно, нужно что-то вроде «производить». –