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 4: Talking to Servers(その1)

Posted at

Chapter 4: Taking to Servers

  • Richard Feldman, Elm in Action MEAP V03, pp.88-119
  • 30ページくらいあるうちの今回は1/3くらい
    • 他は、http通信と副作用、JSONデコードなどが話題としてあるがそれは11日目以降で

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

Modelの型定義をMaybeを使って書き直す

アプリデータはサーバーから取ってくるようにすると、この型定義はまずくなる

type alias Photo =
    { url : String }

type alias Model =
    { photos : List Photo
    , selectedUrl : String
    , chosenSize : ThumbnailSize
    }

これを書き直す

  • Photo型はこのままでokなのは、必ずメンバーを含むという型ではないから
  • データがなければ、画像のurlも選択しようがないし、サイズも選び様が無い、ということを型定義に踏まえてく
type alias Model =
    { photos : List Photo
    , selectedUrl : Maybe String
    , loadingError : Maybe String
    , chosenSize : ThumbnailSize
    }

モデルのフィールドを取り出す、簡潔な書き方

無名関数作って冗長にやってたところをスッキリかける

-- これは、
\photo -> photo.url
-- こう書ける
.url

Maybe.map

Maybe a型のaRecord型でフィールドの値を取り出したい場合にスッキリ書ける

newSelectedUrl : Maybe String
newSelectedUrl =
    case newSelectedPhoto of
        Just photo ->
            Just photo.url

        Nothing ->
            Nothing

Photo型のurlフィールドの値を取り出すために、Just aのブランチでまた別のJust..を返すという少し冗長な書き方をしてるときに、Maybe.mapつかうと

newSelectedUrl : Maybe String
newSelectedUrl =
    Maybe.map (\photo -> photo.url) newSelectedPhoto

とスッキリ書ける

関数のネストとパイプ演算子、|>

ある戻り値を得るのに、複数の関数呼び出しをするような関数について読みやすくするために用意されてるのだと理解した

  • パイプ演算子には、逆向き(<|)もあるが、こっちの意義というか使い所はわかってない

前に、「Elmでは関数の戻り値は1つだけで引数も1つだけ」でも書いたが、Elmの関数の引数は1つなので

padLeft : Int -> Char -> String -> String
String.padLeft 9 '.' "not"

は実際は

padLeft : Int -> (Char -> (String -> String))
(((String.padLeft 9) '.') "not")

というふうに複数の関数呼び出しを行ってるが、Elmでは、カッコを外せて、読みやすく書きやすくなってる

テクニカルには、左結合だから外せる、と説明されてる

The reason we can avoid writing the parenthesis is because function application associates to the left.

これは、使われる引数が左から並んでるバージョンだったが、逆のバージョンもある

newSelectedUrl : Maybe String
newSelectedUrl =
    Maybe.map .url (Array.get index (Array.fromList model.photos))

Maybe.map .url (Array.get index (Array.fromList model.photos))

  • Maybe.mapのとこで説明したnewSelectedPhoto(Array.get...)と、インラインで書いてる
  • Array.fromList model.photosから、Maybe.map .urlへと右から順番に読まなくていけない
  • これをString.padLeft 9 '.' "not"同様に、左から右へと書くために使えるのが、パイプ演算子|>
newSelectedUrl : Maybe String
newSelectedUrl =
    model.photos
        |> Array.fromList
        |> Array.get index
        |> Maybe.map .url
  • [引数] |> [関数]という構造に変換
  • 右側の引数を左側の関数に渡して、関数呼び出し
  • Array.get indexMaybe.map .urlやそれ自体引数を取った関数呼び出しだが、関数を返すので、[引数] |> [関数]の構造に沿ってる
  • コンパイル時には、変換前のカッコのついた右から読むバージョンに変換されるらしいのでパフォーマンスのデメリットはない

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