Open14

The Elm Archtecture

ShebangDogShebangDog

typetype aliasの違いは?

type

typeがなんなのかはわかっていない。
使われ方としてはsealed classに似ている気がする

type.elm
type Either
 = Loading
 | Success { value: Int }
 | Failure { message: String }

getValue : Either -> String
getValue either = 
  case either of
    Loading -> "loading"
    Success v -> "success"
    Failure message -> "failure"

type alias

type aliasは型に名前をつけるもの

typeAlias.elm
type alias T = { value: Int }
ShebangDogShebangDog

typeはカスタム型の宣言に利用するみたいだ
また別名がtagged unionやADTと呼ばれていることからseald classはあながち間違っていなそう

ShebangDogShebangDog

type aliasはレコードを作ってる

typeAlias.elm
type alias T = { value : Int } 

T // <function> : Int -> T 
typeAliasLike.elm
record : Int -> T
record first = { value = first }

record // <fucntion> : Int -> { value : Int }

typeAlias.elmtypeAliasLike.elmはほぼほぼ同じ

ShebangDogShebangDog

type aliasはレコードを作る際に、コンストラクタを生成する

ShebangDogShebangDog

typeもtype aliasもコンストラクタは作ってそう

コード
constructor
type T
    = A
    | B String
    | C String Int

a : T
a = A

b : String -> T
b = B

c : String -> Int -> T
c = C

type alias TA =
    { 
    }

type alias TB =
    { a : String
    }

type alias TC =
    { a : String
    , b : Int
    }

ta : TA
ta = TA

tb : String -> TB
tb = TB

tc : String -> Int -> TC
tc = TC
ShebangDogShebangDog

scalaでいうunapply?等を作ってくれるか作ってくれないかの違いはありそう

なんか違うかも?recordであれば以下で分解できる。
let {x, y} = position

variantならcase ofで分解?できる

ShebangDogShebangDog

エラーハンドリング

型にエラー情報を逃す。ResultMaybeでそれを実現する

Maybe

JavaのOptionと同等のものでnull参照をなくす

maybe.elm
type MaybeInt
  = Value number
   | Nothing

toInt : String -> MaybeInt
toInt string = 
  case String.toInt string of
    Nothing -> Nothing
    Just value -> Value value

Result

よく聞くEither
例外処理用の型

result.elm
type Either value error
 = Just value
  | Err error
ShebangDogShebangDog

#コマンドとサブスクリプション

Html msgでHTMLエレメントからメッセージを送るように、Cmd msgでコマンドからメッセージを送れる。

ShebangDogShebangDog

そもそもElmが最大限生かされる書き方ってどんなんなんだろう?
MVCを深く知ると良いのかな??

ShebangDogShebangDog

Lens触ってみた。真価はわからない

import Html exposing (text)
import Monocle.Lens exposing (Lens, modify)


type alias User =
      { name : String
      , age : Int
      }

user : User
user = User "" 1

userNameLens : Lens User String
userNameLens = 
  let 
    get u = u.name
    set n u = { u | name = n }
  in
  Lens get set
  
userAgeLens : Lens User Int
userAgeLens = 
  let 
    get u = u.age
    set a u = { u | age = a }
  in
  Lens get set

increment : Int -> Int
increment value = value + 1

main = text (String.fromInt ((modify userAgeLens increment) user).age)