search
LoginSignup
3

More than 5 years have passed since last update.

posted at

updated at

Organization

ElmのMailbox

追記
この記事は古いです。過去のものです。忘れてください

はじめに

この記事はElm Advent Calendar13日目の記事です

わかること

ElmのSignal.Mailboxが何者なのか分かる。
公式ドキュメントに書かれている内容とコードを読んで分かったことが書いてある。

わからないこと

Nativeモジュール(javascriptで書かれた部分)の中身。読んでません。

version

exact-dependencies.json
{
    "elm-lang/core": "3.0.0"
}

MailBox

ざっくりいうと

ドキュメントにはまさにMailbox!みたいなことが書いてあります(確か)
Address(住所)にメッセージ(値)を送ると、Mailbox(郵便箱)を持っている人が受け取って見ることができます。
まさにMailbox!

ただメッセージを送る、というお仕事は副作用なので明示的にportなどを使って送らねばなりません。

やってみましょう。Try Elmに貼ればそのまま実行できます。

Main.elm
import Graphics.Element exposing (..)
import Task exposing (Task)

main = Signal.map show mailbox.signal

mailbox = Signal.mailbox "最初のメッセージ"

port post : Task.Task x ()
port post = Signal.send mailbox.address "次のメッセージ"

実行してみると、一瞬「最初のメッセージ」が実行された後「次のメッセージ」が表示されます

Mailboxを作るにはSignal.mailbox関数を使います。引数には初期値を与えています。この初期値が最初に画面に表示されています。

値はmailbox.signalで取り出せますが、名前からわかる通りSignal a型の値です。mailbox.addressに値を送ると値が変わるSignalですね

送り方は、手動で送る場合Signal.sendを使ってTaskにしてportを使って送ることです。
portを付けられたTaskは実行されます。sendで作られるTaskは与えられたaddressにメッセージを送ります

上の例では自分でportを使ってメッセージを送っていますが、The Elm ArchitectureなどではHtml.EventsのonClick関数にaddressとメッセージを与えてクリックされたらメッセージが送られるようになっています。
ここら辺の動きはNativモジュール内で定義されているので気になったら追ってみるといいかもしれません。

Mailboxに関してその他

関連する関数として、Signal.messageとSignal.forwardToがあります。

Signal.messageはGraphics.Inputで使われています。一方、elm-htmlではaddressが使われています。使い方的にはほぼ一緒に見えるのでなんで違うのかはよくわかりません。

Signal.forwardToは転送用のアドレスを作る関数です。先ほどのAddressはStringを送れましたが、送る時に値を変換したりしてStringにしてから送りたい場合に使えます。

mailbox :Maybe Stringに送りたいときに、send mailbox.address (Just "メッセージ")とやるのではなくStringを直接送れるstringAddress = Signal.forwardTo mailbox.address Justを作ってから、send stringAddress "メッセージ"で送れるようになります。

まとめ

MailboxはまさにMailbox!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3