2016-10-17 5 views
1

以下の(汚い、おそらくインコヒーレント)Purescriptコードは、ボタンが押されたときのWebSocketにいくつかのテキストを送信おもちゃテルミット/ WebSocketのスクリプトです:{}のReactClassの小道具は時々しかないのはなぜですか?

module Main where 

import Prelude 
import React as R 
import React.DOM.Props as RP 
import ReactDOM as RDOM 
import Thermite as T 
import Control.Coroutine (cotransform, connect, runProcess, Producer, Consumer, consumer, producer, emit, ($$)) 
import Control.Coroutine.Aff (produce', produceAff, produce) 
import Control.Monad.Aff (launchAff, runAff, Aff) 
import Control.Monad.Aff.AVar (AVAR) 
import Control.Monad.Aff.Class (liftAff) 
import Control.Monad.Eff (Eff) 
import Control.Monad.Eff.Class (liftEff) 
import Control.Monad.Eff.Console (CONSOLE, log) 
import Control.Monad.Eff.Exception (EXCEPTION) 
import Control.Monad.Eff.Var (($=)) 
import Control.Monad.Writer (lift) 
import DOM (DOM) as DOM 
import DOM.HTML (window) as DOM 
import DOM.HTML.HTMLAnchorElement (download) 
import DOM.HTML.Types (htmlDocumentToParentNode) as DOM 
import DOM.HTML.Window (document) as DOM 
import DOM.Node.ParentNode (querySelector) as DOM 
import Data.Either (Either(..)) 
import Data.Generic (class Generic, gShow) 
import Data.Maybe (fromJust, Maybe(..)) 
import Data.Nullable (toMaybe) 
import Partial.Unsafe (unsafePartial) 
import React.DOM (text, p', td', input, tr', tbody', th, thead', table, div, h1', button) as R 
import Unsafe.Coerce (unsafeCoerce) 
import WebSocket (WEBSOCKET, Connection(..), Message(..), URL(..), runMessageEvent, runMessage, newWebSocket) 

data Action = SendButtonPress | SetText String 

derive instance genericAction :: Generic Action 

instance showAction :: Show Action where 
    show = gShow 

type State = { connection :: Connection 
      , someText :: String 
      } 

initialState :: Connection -> State 
initialState socket = { connection: socket 
         , someText: "" 
         } 

render :: T.Render State _ Action 
render dispatch _ state _ = 
    [ R.p' [ R.text "Value: " 
     , R.text $ show state.someText 
     ] 
    , R.p' [ R.input [ RP.placeholder "Enter rubbish here" 
        , RP.onChange \e -> dispatch (SetText (unsafeCoerce e).target.value) 
        ] [] 
     , R.button [ RP.onClick \_ -> dispatch SendButtonPress ] 
        [ R.text "Send"] 
     ] 
    ] 

performAction :: T.PerformAction _ State _ Action 
performAction SendButtonPress _ state  = void $ lift (sendMsg state.someText state.connection) 
performAction (SetText s) _ _ = void $ T.cotransform $ _ { someText = s} 

sendMsg :: forall a eff. (Show a) => a -> Connection -> Aff (ws :: WEBSOCKET, err :: EXCEPTION | eff) Unit 
sendMsg m (Connection s) = liftEff $ s.send (Message (show m)) 

spec :: T.Spec _ State _ Action 
spec = T.simpleSpec performAction render 

wsProducer :: forall eff. Connection -> Producer String (Aff (avar :: AVAR, err :: EXCEPTION, ws :: WEBSOCKET | eff)) Unit 
wsProducer (Connection s) = produce \emit -> do 
    s.onmessage $= \event -> do 
    emit $ Left $ runMessage (runMessageEvent event) 

wsConsumer :: forall t22 eff t31. (Show t31) => Consumer t31 (Aff (console :: CONSOLE | eff)) t22 
wsConsumer = consumer \msg -> do 
    liftEff $ log $ show msg 
    pure Nothing 

main :: Aff (avar :: AVAR, dom :: DOM.DOM, err :: EXCEPTION, ws :: WEBSOCKET, console :: CONSOLE) Unit 
main = do 
    socket <- liftEff $ newWebSocket (URL "ws://echo.websocket.org") [] 
    let state = initialState socket 
    component <- liftEff (gitItInTheDOM state) 
    runProcess (connect (wsProducer socket) (wsConsumer)) 

gitItInTheDOM :: forall eff props. State -> (Eff (dom :: DOM.DOM | eff) (R.ReactClass props)) 
gitItInTheDOM state = do 
    document <- DOM.window >>= DOM.document 
    let aJarOfSomeSort = DOM.querySelector "#container" (DOM.htmlDocumentToParentNode document) 
    container <- unsafePartial (fromJust <<< toMaybe <$> aJarOfSomeSort) 
    let component = T.createClass spec state 
    -- RDOM.render (R.createFactory component {}) container 
    pure component 

私の質問を約gitItInTheDOMRDOM.renderラインがあるときでありますコードのコメント解除を解除しました。これはエラーメッセージです:

gitItInTheDOM :: forall eff. State -> Eff (dom :: DOM.DOM | eff) Unit 
gitItInTheDOM state = void do 
    document <- DOM.window >>= DOM.document 
    let aJarOfSomeSort = DOM.querySelector "#container" (DOM.htmlDocumentToParentNode document) 
    container <- unsafePartial (fromJust <<< toMaybe <$> aJarOfSomeSort) 
    let component = T.createClass spec state 
    RDOM.render (R.createFactory component {}) container 

しかし、それはどのようにコンポーネントを返却し、まだチェックを入力することができ、コンポーネントをしてください返さない:?

Could not match type 

    {}                           

    with type                          

    props1                          


while trying to match type ReactClass {}                   
    with type ReactClass props1                     
while checking that expression (bind ((bind window) document)) (\$4 ->           
                    case $4 of          
                    document -> ...        
                   )             
    has type Eff                         
      (dom :: DOM                      
      | eff0                        
      )                         
      (ReactClass props1)                     
in value declaration gitItInTheDOM                    

where props1 is a rigid type variable                   
     bound at line 91, column 1 - line 97, column 8               
     eff0 is a rigid type variable                    
     bound at line 91, column 1 - line 97, column 8 

これにgitItInTheDOMを変更することがチェック入力しませんか型チェッカーはpropsというパラメータがの{}にしか受け入れられないようですが、私はこれらの状況が何であるのか理解できず、なぜタイプチェックでもないのです。

成分をpuringのアイデアは、mainに「Driver」をバック渡す次いでwsConsumerに渡すことができ、新たなメッセージがのWebSocketを介して受信された場合(テルミット/リアクトを使用して)、DOMを更新することが可能となるで。もしこれが意味をなさないならば、これが私がやろうとしていることを達成するための有効な方法であるかどうかもわかりません。どのようにそれを有効にすることができますか?あなたは

gitItInTheDOM :: forall eff. State -> (Eff (dom :: DOM.DOM | eff) (R.ReactClass _))

に元の型シグネチャを変更した場合

答えて

2

これはです。TypeCheck、そしてあなたのワイルドカードのために不足しているタイプを教えてください。

なぜですか?

これは普遍的な定量化についてのものです。元のタイプにはforall propsが含まれているため、propsのインスタンス化を選択したタイプの場合は、gitItInTheDOMの定義が意味を持ちます。実際には、あなたのスペックはrenderperformActionで小道具を使用しないようT.createClassから返されたコンポーネントは、任意のpropsためReactClass propsタイプを与えられることができるので、これはOKです - あなたがこれを見ることができ、明示的に導かれたspecのためのタイプを書き出すことにより、コンパイラの_に関する苦情によって。あなたのコンポーネントをレンダリングする行のコメントを解除するとき

はしかし、R.createFactory機能がpropsためあらゆるタイプのために働くことをあなたの主張と矛盾する、特定のタイプ{}propsを固定し、値{}に付属されています。

戻り値の型(... R.ReactClass {})を修正するか、呼び出し元が任意のタイプの小道具を渡すことができます。

関連する問題