ElmArchitectureを始めたのですが、基本言語仕様が頭に入っておらず動いているソースをみても「この書き方って結果どうなるの?」でググることが多いので自分メモで整理したいと思います
いろんなサイトから写経させていただいた自分メモ用なので読み飛ばしてもらってOKです^^;
参考:Elmのシンタックス - Galapagos Blog
リテラル
> 'a' 'a' : Char > "HelloWorld!" "HelloWorld!" : String > True True : Bool > False False : Bool > 1000 1000 : number > 1.0 1 : Float > (1, "abc") (1,"abc") : ( number, String ) -- Tuple > [1, 2, 3] [1,2,3] : List number -- List
Elmでの関数
- 同じ引数に対して同じ結果を返す
- 引数の状態を変えてはいけない
- Elmはイミュータブルな世界なので変えられない
関数
add : Int -> Int -> Int add x y = x + y
add
関数Int -> Int -> Int
は引数 -> 引数 -> 戻り値
を意味する
無名関数
\x y -> x + y
- 先頭に
\
をつける - 上記は引数2つを受け取り、足した結果を返す
引数なし関数
name : String "Taro"
- 定数となる
グループ化
- 関数の結果を別の関数の引数に渡したい場合に
()
を使う - グループ化しなと
multiply
が addの引数とみなされてしまう
multiply :Int -> Int -> Int multiply x y = x * y add 3 (multiply 1 2) -> 5
- パイプ演算子を利用すると見やすくすることができる
add 3 <| multiply 1 2 -> 5 2 |> multiply 1 |> add 3 -> 5
- 1 を multiply の第一引数に渡す
- 2 を multiply の第二引数に渡す
- multiply の結果を add の第一引数に渡す
- 3 を add の第二引数に渡す
パイプオペレータ
2 |> power -- 左から右へ渡す power <| 2 -- 右から左へ渡す
関数の応用
関数が引数
funcArg: (Int -> Int) -> Int -> Int funcArg func x = func xa -- 利用方法 funcArg (\x -> 2 * x) 2
関数が戻り値
funcReturn : (int -> Int) funcReturn = \x -> 2* x -- 利用方法 func = funcReturn func 2
型
- 型パラメータとか
- ジェネリックになる
type alias
- 型に別名をつける
func :String -> String -> Int -- 上よりも下のほうがわかりやすく堅牢 type alias Id = String type alias Name = String func : Id -> Name -> Int
再帰定義
- 型を再帰的に利用することができる
type Human = human { id : Int , name:String , sex: Int , birthday: String , father: human , mother:human } or type alias Human = { id : Int , name:String , sex: Int , birthday: String , father: InHuman , mother: InHuman } type InHuman = InHuman Human
Union Type
- 複数の定数を1つの型で使えるようになる
- Enumみたいなもの
|
でつなぐ
type Result = Ok | Ng checkResult result = case result of Ok -> True Ng -> False checkResult Ok --> True checkResult Ng --> False
Recodes
- Key : Valueのセットを持つ
- イミュータブルなので変更するには新しいレコードを作る必要がある
type alias User = {id : Int, name : String} user = User 1 "taro" user.id --> 1 user.name --> "taro" newUser = {user | name = "jiro"}
Listの関数
filter
- 判定方法を実装した関数とListを渡すと、判定結果を満たしたListを返す
List.filter (\x -> x % 2 == 0) [1, 2, 3] --> 結果[2]
map
- 変換方法を実装した関数とListを渡すと、List要素すべてに関数を適用したListを返す
List.map (\x -> x * 2) [1, 2, 3] --> 結果[2, 4, 6]
Maybe
- Java8の
Optional
と同じ - あり -> Just
- なし -> Nothing
type Maybe a = Just a | Nothing Just 1
map
- 変換方法を実装した関数とMaybeを渡すと Justの場合は、関数で変換 Nothingの場合は、なにもしない
Maybe.map (\x -> toString x) Just 1 -> "1" Maybe.map (\x -> toString x) Nothing -> Nothing
withDefault
- デフォルト値とMaybeを渡すと Justの場合は、要素を取り出す Nothingの場合は、デフォルト値を返す
Maybe.withDefault 0 <| Just 1 --> 1 Maybe.withDefault 0 Nothing -- 0
構文
if
- if文ではなく式なので評価された値を返す
- elseは必須で省略はできない
if True then "a" else "b" [結果] "a" if Flase then "b" else "a" [結果]"b" count = 1 if count < 0 then "less then zero" else if count == 0 then "equal zero" else "over zero" [結果] "over zero"
case
_
は多言語のdefaultと同じ
case [式] of [条件] -> [結果] _ -> [結果]
if同様に式なため評価結果を返す
level = 99 case level of 1 -> "Level min" 99 -> "Level max" _ -> "Other Level" [結果]"Level max"
let
- 値を変数に入れて使うことができる
let a = 1 + 1 (b, c) = (2, 3) in a * b * c -> 12
再帰
- ループはない
- Collection系に定義されている関数を使うか再帰を使う
sum : List Int -> Int sum list = case list of [] -> 0 x :: xs -> x + sum xs sum [] --> 0 sum [1, 2, 3] --> 6
モジュール
- モジュール=ファイル
- モジュール名はファイル名と一致している必要がある
**
Common.StringUtils
ならCommon/StringUtils.elm
宣言
-- すべて公開 module Hoge exposing (..) -- 一部公開 module Hoge exposing (func,fuga(..))
import
import Hoge Hoge.func -- 別名 import Hoge as hoge hoge.func -- 直接 import Hoge exposing(func) func
デフォルトimport
- 以下はデフォルトで読み込まれているので宣言不要
import Basics exposing (..) import Debug import List exposing ( List, (::) ) import Maybe exposing ( Maybe( Just, Nothing ) ) import Result exposing ( Result( Ok, Err ) ) import Platform exposing ( Program ) import Platform.Cmd exposing ( Cmd, (!) ) import Platform.Sub exposing ( Sub )