LoginSignup
7
11

More than 5 years have passed since last update.

今日から始めるelm-lang

Last updated at Posted at 2016-07-13

elm-lang

compileするとJSが吐き出されるalt JS的なもの。
文法がHaskellに近いらしい。
文法と関数の定義との関連が直感的にわかりやすいのが個人的に◎
言語について詳しく知りたい場合は、以下の記事がおすすめです。
http://qiita.com/mizchi/items/1c707342dd008af61118#_reference-7a151034909cd14c9e7d
http://qiita.com/mizchi/items/1c707342dd008af61118#_reference-7a151034909cd14c9e7d

install

私はinstallerを使いました。
brewを使うと0.17がinstallされます。(最新は0.17.1)

editor

vscodeでelmと検索してPluginをinstallすると捗ります。
公式ではsublimeおすすめとありましたが、頻繁に購入ダイアログが出てくるのと、vscode以上の機能がないのでやめました。
code <fileName>で開けるようにPATHを通すと捗ります。(コマンドパレットでcommandで検索すると出てくるはずです。)

入門

とりあえずここを読むだけで良い感じ。
適宜、coreやhtmlライブラリのコードを読むと捗ります。

exerciseやってみた

ここの2つのダイスを回すものをやってみました
http://guide.elm-lang.org/architecture/effects/random.html

module Main exposing (..)

import Html exposing (..)
import Html.App as Html
import Html.Events exposing (..)
import Random


main =
    Html.program
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }



-- MODEL


type alias Model =
    { dieFace : Int
    , twoFace : Int
    }


init : ( Model, Cmd Msg )
init =
    ( Model 1 1, Cmd.none )



-- UPDATE


type Msg
    = Roll
    | NewFace ( Int, Int )


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Roll ->
            ( model, Random.generate NewFace (Random.pair (Random.int 1 6) (Random.int 1 6)) )

        NewFace ( newFace, twoFace ) ->
            ( Model newFace twoFace, Cmd.none )



-- SUBCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.none



-- VIEW


view : Model -> Html Msg
view model =
    div []
        [ h1 [] [ text (toString model.dieFace) ]
        , h1 [] [ text (toString model.twoFace) ]
        , button [ onClick Roll ] [ text "Roll" ]
        ]

Random.pairを使う練習みたいですね。

HTTPのやつもやってみました
http://guide.elm-lang.org/architecture/effects/http.html

module Main exposing (..)

import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http
import Json.Decode as Json
import Task


main =
    Html.program
        { init = init "cats"
        , view = view
        , update = update
        , subscriptions = subscriptions
        }



-- MODEL


type alias Model =
    { topic : String
    , gifUrl : String
    , errorMsg : String
    }


init : String -> ( Model, Cmd Msg )
init topic =
    ( Model topic "waiting.gif" ""
    , getRandomGif topic
    )



-- UPDATE


type Msg
    = MorePlease
    | FetchSucceed String
    | FetchFailed Http.Error
    | Name String


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        MorePlease ->
            ( model, getRandomGif model.topic )

        FetchSucceed newUrl ->
            ( Model model.topic newUrl "", Cmd.none )

        FetchFailed error ->
            case error of
                Http.Timeout ->
                    ( { model | errorMsg = "timeout error" }, Cmd.none )

                Http.NetworkError ->
                    ( { model | errorMsg = "network error" }, Cmd.none )

                Http.UnexpectedPayload payload ->
                    ( { model | errorMsg = "unexpected payload" }, Cmd.none )

                Http.BadResponse code status ->
                    ( { model | errorMsg = "badresponse" }, Cmd.none )

        Name newTopic ->
            ( { model | topic = newTopic }, Cmd.none )



-- VIEW


view : Model -> Html Msg
view model =
    div []
        [ input [ type' "text", placeholder "topic", onInput Name ] []
        , select [ onInput Name ] [ option [ value "cats", selected True ] [ text "cats" ], option [ value "dogs" ] [ text "dogs" ], option [ value "akb48" ] [ text "akb48" ] ]
        , button [ onClick MorePlease ] [ text "More Please!" ]
        , br [] []
        , h2 [] [ text model.errorMsg ]
        , img [ src model.gifUrl ] []
        ]



-- SUBSCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.none



-- HTTP


getRandomGif : String -> Cmd Msg
getRandomGif topic =
    let
        url =
            "//api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=" ++ topic
    in
        Task.perform FetchFailed FetchSucceed (Http.get decodeGifUrl url)


decodeGifUrl : Json.Decoder String
decodeGifUrl =
    Json.at [ "data", "image_url" ] Json.string

selectの値取得はonInputでOKのようです。

HTTP Package

eml-package install evancz/elm-httpでインストールする。

Resultについて

Result.Result a bからbを取得する場合、Result.withDefault b (Result.Result a b)のようにすればOK

$ elm-repl
> import String
> import Result
> Result.withDefault 1 (String.toInt "23") --- 第2引数はfunctionであること

Project Setup

$ mkdir -p $HOME/dev/elm/sandbox
$ elm-package install
$ cd $HOME/dev/elm/sandbox
$ code ./

Pakcage更新時にelm-reactorの挙動が変になる?

coreを4.0.1->4.0.2に更新した後、elm-reactorを動作させたら表示されなくなりました。
elm-stuffディレクトリを削除してelm-package installしたら戻りましたが、調査が必要ですね。

まとめ

書いていてかなり楽しいですね。
特に関数の定義と実装が直感的なのが素晴らしいと思います。

7
11
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
7
11