new User(1, "aaa") val user2 = User(1, "aaa") val user3 = User.apply(1, "aaa") val user4 = User apply (1, "aaa") type alias User = { id : Int, name : String } user = User 1 "aaa" Scala Elm たった1通りの生成手段(多分) 複数の生成手段 もちろんただ冗長な訳ではなく, applyはファクトリメソッドを表す 7
c = 10 def f(x: Int, y: Int, z: Int) = x + y + z f(a,b,c) } sum: Int -> Int -> Int sum a b = let -- 変数cのスコープはlet式内でのみ有効 c = 10 f x y z = x + y + z in f a b c Scala Elm 9 let式はない
OK "a" + 1.toString // OK 1 ++ "a" -- コンパイルエラー "a" ++ 1 -- コンパイルエラー "a" ++ String.fromInt 1 -- OK "a" ++ 1 ^ Try using String.fromInt to turn it into a string? Scala Elm 暗黙の型変換により コンパイラがよしなに型変換をしてくれる 勝手に型変換はしないが 代わりに親切なエラーを出してくれる 11
object Dog extends Animal sealed trait Fruit case class Apple(id: Int) extends Fruit case class Banana() extends Fruit def message(fruit: Fruit): String = { fruit match { case Apple(1) => "apple-1" case Apple(_) => "apple-any" case Banana() => "banana" } } type Animal = Cat | Dog -- 値を持たせたり type Fruit = Apple Int | Banana message: Fruit -> String message fruit = case fruit of Apple 1 -> "apple-1" Apple _ -> "apple-any" Banana -> "banana" Scala Elm カスタム型に値を持たせる場合,フィールド名 は指定出来ないので,専用の型を定義する必 要がある 12
None List(1).head > Int = 1 List().head > java.util.NoSuchElementException: head of empty list List.head [1] > Just 1 List.head [] > Nothing Scala Elm nullを表現する場合はMaybeなどでラップする nullを表現する場合はOptionなどでラップする ただし,例外処理を使っても良い 13
List.map String.fromInt |> String.join "," > "1,2,3" Scala Elm コレクションが持つメソッドを呼び出してチェー ン 異なるモジュール同士をつなぐ List.range 1 3 |> List.map String.fromInt List Int List Int -> List String 14
a + b + c def add(a: Int)(b: Int)(c: Int): Int = a + b + c add: Int -> Int -> Int -> Int add a b c = a + b + c <function> : number -> number -> number -> number > add a b c = a + b + c <function> : number -> number -> number -> number > add 1 <function> : number -> number -> number Scala Elm ((add a) b) c みたいに 必ず1つの引数しか渡せない カリー化するかは自分で判断 15