# 自作言語 案 ## 構文 ### 方針 - Python に寄せた構文 - 記号はあまり使わない - インデントはタブ - インデントによるブロックは**必ず**その前の行の最後が `:` - インデントは次の場合にしか使わない - ブロック - 一つの式を複数行にわたって記述する - この場合改行 + それ以降の式は 1 インデント - 記号ではなくなるべく文字を使う - パターンマッチのパターンにできるものは大文字、それ以外は小文字 - 多相バリアント ### コメント ```= # コメント #- 複数行 -# ``` ### ラムダ式 ```= f: Int -> Int f = lambda(x): x + 1 //同値 f: Int -> Int def f(x): x + 1 ``` 複数引数のラムダ式 ```= f: Int -> Int -> Int f = lambda(x, y): x + y f: Int -> Int -> Int def f(x, y): x + y ``` 自動でカリー化される 上のは下と同値 ```= f = lambda(x): lambda(y): x + y; f: Int -> Int -> Int def f(x): lambda(y): x + y; ``` ### let ブロック def, lambda 式で使える return の右の式が帰る ```= def f(x): y = 2 return x + y f = lambda(x): y = 2 return x + y ``` また、let ブロックとしても使える ``` x : Int = let: y = 2 z = 3 return y + z ``` ### Context context 文で async await 的なことが出来る ```= main : Context (EFF Void) Unit main = context: log("Hello World") # log : forall a op. Show a => a -> Context (EFF op) Unit x <- random # random : forall op. Context (EFF op) Double y = x + 1 # 単なる代入 log(y) return unit ``` いわゆる Extensible Effects ### パターンマッチ ```= x = match y: case Just(z : Int) if w == z: z + 1 case Nothing: 0 ``` ### if 式 ```= x = if w == z: 1 else: 0 ``` ### 演算子 ``` +, *, -, /, % ==, !=, <, >, =<, =>, &&, || ++ # 配列、文字列の結合 |>, <| # パイプライン ``` ### 型アノテーション 定義の時、引数に書ける ```= f : Int -> Int f = lambda(x: Int): x + 1 ``` ### type 宣言 ```= type Hoge: Fuga : Int -> Hoge Piyo : String -> Hoge FugaFuga : Hoge type Maybe(t): Nothing Just(t) ``` ### ジェネリクス、制約 ```= mp : forall t u. (t -> u) -> t -> u def mp(f, x): f(x) append : forall t. Monoid t => t -> t -> t append = ... ``` ### 拡張可能バリアント ```= type Foo(a): Foo: forall y. Int -> Foo(x) a type Bar(x): Bar: forall x. String -> Bar(x) x ``` ### クラス ```= class Semigroup<t>: append : t -> t -> t class Monoid<t when Semigrop<t>>: empty: t instance Semigroup<String>: append = ... instance Monoid<String>: empty = "" class Reader<m when Monad<m>>: type t: Type read: m<t> ``` ## FFI ### 外部 data 型 ```= foreign data HtmlDivElement :: Type; ``` ### 値のインポート 別ファイル ```javascript= const plusOne = (x) => x + 1 ``` ```= foreign plusOne: Int -> Int; ```