Skip to content

Instantly share code, notes, and snippets.

@cesare
Last active September 17, 2015 04:48
Show Gist options
  • Save cesare/db68af3db58f43586b96 to your computer and use it in GitHub Desktop.
Save cesare/db68af3db58f43586b96 to your computer and use it in GitHub Desktop.

社内勉強会 Elm 篇

Elm

  • AltJS (?)
  • 関数型
  • Haskell っぽい構文
    • モナドとか出てこない
    • 遅延評価はない
  • Reactive / FRP

情報源

インストール

  • elm-platform http://elm-lang.org/install
    • 素直にバイナリインストールでok
    • 各種エディタ向けのプラグイン的なやつもここに

elm-platform

# いわゆる REPL
$ elm repl

# コンパイル的なやつ
$ elm make

# パッケージを取ってくる
$ elm package install evancz/task-tutorial

# ブラウザで見える環境を作る
$ elm reactor

試してみる

$ git clone git@github.com:evancz/elm-examples.git
$ cd elm-examples

# ひとまずブラウザで見える環境を作ってみる
$ elm reactor
# → http://0.0.0.0:8000/
# Mario.elm とかを開く

# ビルドしてみる
$ elm make
# → ./elm-stuff 配下などを覗いてみる

リテラルとか構文とか

$ elm repl
-- 数値

123
1.234

-- 文字列
"Hello, world!"

-- キャラクター
'c'

-- Boolean
True
False

-- Null 的なやつ
null  -- エラー
Null  -- エラー
nil   -- エラー
Nil   -- エラー
-- null は存在しない

-- 配列 (と言うかリスト)
[1, 2, 3]
["foo", "bar", "baz"]

['a', 'b', 'c'] -- => 文字列 "abc" とはならない

["foo", 123] -- => エラー。型が違う値を混在できない

[1..10] -- => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1..10 -- => エラー。そんなものはない

--- 要素へのアクセス
[1..10][0]  -- => エラー。こういう構文はない

List.head [0..10] -- => Just 0
List.drop 3 [0..10] |> List.head -- => Just 3

--- 連結
1 :: [2, 3,] -- => [1, 2, 3]
[1, 2, 3] ++ [4, 5, 6] -- => [1, 2, 3, 4, 5, 6]

-- タプル
(1,2)
("foo", 123)

-- オブジェクト的なやつ
object = {x = 123, y = 987}
object.x -- => 123
object.y -- => 987

--- 値の更新
{object | x <- 200}
{object | z = 345}

-- パターンマッチング的なやつ
case ("foo", 123) of
  ("foo", x) -> Just x
  (_, x) -> Nothing

-- 条件分岐
if x > 0 then x else 0

-- 関数
square n = n^2
squareSum x y = x^2 + y^2

-- 関数適用
square 3  -- => 9
squareSum 4 5 -- => 41
squareSum 4 -- => <function> number -> number
(+) 1 2 --> 3

-- 無名関数
(\x -> x^2)
(\x y -> x^2 + y^2)

-- List 操作
List.map (\n -> n^2) [1..10]  -- => [1,4,9,16,25,36,49,64,81,100]
List.foldl (+) 0 [1..10]

-- |>, <|
List.foldl (+) 0 (List map (\n -> n^2) [1..10])
[1..10] |> List.map (\n -> n^2) |> List.foldl (+) 0  -- => 385

-- Maybe
Just 123
Just "foo"
Just [1,2,3]
Nothing

Maybe.map (\n -> n^2) (Just 12)  -- => Just 144
Maybe.map (\n -> n^2) Nothing    -- => Nothing

List と Maybe

  • どちらも「値を包んだもの」
    • List は0個以上の値を包んだもの
    • Maybe は0個か1個の値を包んだもの
  • map は「包み」を受け取って同じ種類の別の「包み」を返す
    • map する関数は「包み」を意識しない (中の値を計算する)
    • 中身が空なら関数は呼ばれない
List.map (\n -> n^2) [1..10]
Maybe.map (\n -> n^2) (Just 5)

List.map (\n -> n^2) []
Maybe.map (\n -> n^2) Nothing

Just 5  |> Maybe.map (\n -> n + 1) |> Maybe.map (\n -> n^2)
Nothing |> Maybe.map (\n -> n + 1) |> Maybe.map (\n -> n^2)

Signal

  • List, Maybe と同じく、値を包んだもの (と考える)
  • 時が経つと値が現れたりする
    • イベントが起きる = 値が生じると考える
      • マウスポインタの位置が変わった
      • キーが押された
      • 一定時間が経過した
      • ネットワークの向こうからパケットが飛んできた
  • Signal.map は関数と別の Signal を取る
Signal.map (\n -> n^2) someSignal
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment