LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

Elm in Action, chapter 3: Compiler as Assistant

Last updated at Posted at 2016-12-09

Compiler as Assistant

学んだこと、目に留まった箇所

Elmではtype annotationはoptional

  • 書かなくてもビルドできる
    • Elm in Actionでも1章、2章のコードでは型定義は書いてなかった
  • elm-make--warnオプションつけると、型推論によって型定義がサジェストされる

3章で取り上げると宣言してること

  • スキップしてきた型定義
  • case
  • データ型として、ArrayMaybe
  • union type
  • commandを使った乱数生成

on boadingコストを下げるツールとしての型定義

  • coolでawesomeな言語で開発されたプロジェクト
    • とてもよいこと。
  • ソースコードへの信頼性は高い。テストも書かずに、ランタイムエラーの出ないアプリかける
    • よいこと。
  • awesomeで信頼性高いコードが書かれてるが、ドキュメントもテストもないし、コードはクリーンアップされてない
    • リソースはコード書いて信頼性高いアプリかくことに全力投下してる
    • こんな状態で新人が参加したらどうすべき?
    • リソース限られた状況で、キャッチアップコストどうやって下げる
  • ドキュメント?、テスト?、ソースの整理?
    • 「最初に型定義」、これがrichardの答え

コメントは嘘が時々書かれてる。コードは嘘が書かれてない。型定義も同じ

  • 書かれた当時は正確でhelpfulなコメントも半年後には正しくないコメントに変わってる可能性
    • コメントがノイズになる
  • 型定義はノイズにならない
    • ビルドが通すことによって、書かれた型定義が正確であることが保証されてる
    • 信頼できる情報源としての型定義

型定義の例

Screen Shot 2016-12-09 at 12.19.20 PM.png

定数

-- 定数
urlPrefix: String

--関数
isEmpty : String -> Bool
isEmpty str = str == "”

ListArrayの違い

  • List
    • リテラルシンタックスあり
      • ['hello', 'world', 'elm']
    • メンバーアクセスは、最初のメンバーだけアクセス可能
    • 任意の位置のメンバーへアクセスできない
    • パフォーマンス性能よいので、ArrayではなくListをつかうべき
  • Array
    • 任意の順番のメンバーへアクセスできる
    • 関数Array.fromの戻り値としてArrayを作られる
      • qualifiedスタイルだと、Array.Array.fromになるので、unqualifiedスタイル推奨
      • import Array exposing (Array)
    • リテラルシンタックスがないので、Array.fromなどを使って生成する

型変数

この辺別エントリでかいた

Elmにおける型変数をもつデータ型の振る舞いについて

「あとで書く」と予告されてる特別な型変数

  • number
  • appendable
  • comparable

型変数は小文字であれば何でもいいが、この3つだけはElmでは特別な意味を持つ、らしい

type alias

type aliasというキーワードつかう

TodoMVCのコードから例をとると、

type alias Model =
    { entries : List Entry
    , field : String
    , uid : Int
    , visibility : String
    }


type alias Entry =
    { description : String
    , completed : Bool
    , editing : Bool
    , id : Int
    }
  • 同じ型定義を繰り返し書くのを回避
  • 修正箇所が1箇所になり、メンテしやすさUP

Htmlの型変数


view : Model -> Html Msg
view model =
  ...skip
  • view関数の戻り値がHtmlではないのはなぜか?
    • Htmlupdate関数に送るメッセージを表現してる
    • msgの型は、ハンドラが送るメッセージの型によって決まる
    • onClickが送るメッセージの型、とか
div [ onClick { x = 3.3 } ] []

- これだと{ x = 3.3 }というメッセージをHtmlが送っている、という意味

type alias Msg =
    { operation : String, data : String }
view : Model -> Html Msg

複数の引数をとる関数の型定義

別エントリで書いた
Elmでは関数の戻り値は1つだけで引数も1つだけ

case式の話

  • jsのif..else文と比較してるところがわかりやすい

Screen Shot 2016-12-09 at 12.51.39 PM.png

_ ->
 model
  • これがjsのelse節、switch文のdefault...に近い
  • アンダースコア_は、作法でなのか、Elmの文法上の理由なのかが、まだわからない

    • 要調べる :nerd:
  • case式はマッチしたらそこで評価が終わる

    • これがjsと違うとこ

case式とunion typesを組み合わせる

  • 通常コードではこっちのパターンが多い
  • 利点は、_ ->...というブランチを消せる点
  • case size of ...というコードで、sizeStringであれば、FETACH_DATAPOST_DATAとか想定してるStringに処理を書くだけで終わらず、「それ以外のStringが来た場合」をかかないといけない
  • でもsizeがunion typeであれば、可能性は列挙されててるので、「それ以外」が存在しない型定義
type PhotoSize = XS| LL | XL

というunion typeをcase式に渡せば、ありうる可能性はXSLLXLだけになる

XLのケースとか書き忘れてると、コンパイラがちゃんとビルド時に警告出すのも便利

“-- MISSING PATTERNS -------------------------------- PhotoGroove.elm
 
This `case` does not have branches for all possibilities.
...
You need to account for the following values:
 
    PhotoGroove.SetSize _
 
Add a branch to cover this pattern!”

Excerpt From: Richard Feldman. “Elm in Action MEAP V03.” iBooks. 

このunion typeの図がよかった

Screen Shot 2016-12-05 at 11.17.36 PM.png

  • XStype constructorです、と言えることがわかったので
  • いつも何て呼べばいいのか困ってた。タグ?、値の1つ?という有様だったので :joy:

Maybe

自分の理解がふわっとしてる箇所

type Maybe value
    = Just value
    | Nothing

Screen Shot 2016-12-09 at 1.15.46 PM.png

  • 値がない可能性を表現するデータ型
  • jsのnullundefinedのようなケースをElmではどう扱っているのか、という部分

戻り値がMaybe a型であるArray.getを使って説明してる

get : Int -> Array a -> Maybe a
  • Arrayのメンバーを取り出すための関数

    • 型変数はaは何でもよい
    • が、ArrayMaybeで同じになってることで、Arrayのメンバーと取り出せる値が同じ型であることが保証
  • メンバーのインデックスがArrayにはない可能性

  • 渡されたArrayが空である可能性

という可能性のときに、Array.get..を評価した結果、Nothingを返す。

getPhotoUrl : Int -> String
getPhotoUrl index =
    case Array.get index photoArray of
        Just photo ->
            photo.url
 
        Nothing ->
            ""

のように使う時は、case式を使って可能性を列挙してどうするかを記述する必要がでてくる

  • 書かないと、コンパイルが通らない
  • Maybe aが戻り値である関数を使う時は、case式使うのが必須
    • 可能性を列挙するように書かざるをえない
    • Elmの「値が無い可能性」に対するアプローチ、ということか
    • ということがわかった

Randomモジュール使って、ランダムにArrayからメンバーとってくる

別エントリにかいた

Elmでランダムな結果を出す処理をどうやるか

0

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
  3. You can use dark theme
What you can do with signing up