Search code examples
signalsfrpelm

Task mixed in a signal


I would like to send a message to mailbox inline with a signal.

module Main where

import Graphics.Element exposing (show)
import Html             exposing (..)
import Html.Attributes  exposing (..)
import Html.Extra       exposing (..)
import Signal

import Model.PickList   exposing (pickList)
import Model.BabyName.Debug as Debug

headerPane : Html
headerPane =
  header [ id "header" ]
  [ text "header" ]

leftPane : Signal Html
leftPane = flip Signal.map (.signal pickList) <| \pl ->
  ul []
  [ li []
    [ fromElement << show <| pl ] ]

mainPane : Html
mainPane =
  section [ id "main" ]
  [ text "what? what?" ]

layout : Signal Html
layout = flip Signal.map leftPane <| \lp ->

  div [ id "wrapper" ] <|
  [ headerPane
  , lp
  , mainPane ]

main : Signal Html
main =
  (Signal.send (.address pickList) Debug.dummyList) -- type error
  layout

I feel like all I need is haskell's >>. But these are Signals (which are not Monads), and there is no do notation or >>= \_ -> kind of madness, neither do I see a liftTask. Is the idea that in Elm you need an external input, and cannot send arbitrarily from the perspective of the application? Please help me understand.


Solution

  • Answer

    Tasks in Elm 0.15 are executed by sending them through a port. That means that your Task or Signal Task needs to be available at the top-level in the Main module, because that's the only place where you can declare a port. This means that you cannot simply send a message to a mailbox in-line (that would be a side-effect), you'll have to make sure that the task can flow through your program to the port definition.

    Example

    import Html             exposing (..)
    import Html.Attributes  exposing (..)
    import Html.Extra       exposing (..)
    import Signal
    
    import Model.PickList   exposing (pickList)
    import Model.BabyName.Debug as Debug
    
    headerPane : Html
    headerPane =
      header [ id "header" ]
      [ text "header" ]
    
    leftPane : Signal Html
    leftPane = flip Signal.map (.signal pickList) <| \pl ->
      ul []
      [ li []
        [ fromElement << show <| pl ] ]
    
    mainPane : Html
    mainPane =
      section [ id "main" ]
      [ text "what? what?" ]
    
    layout : Signal Html
    layout = flip Signal.map leftPane <| \lp ->
    
      div [ id "wrapper" ] <|
      [ headerPane
      , lp
      , mainPane ]
    
    port toPicklist = Signal.send (.address pickList) Debug.dummyList
    
    main : Signal Html
    main = layout
    

    Resources