Reason
  • ドキュメント
  • 試してみる
  • API
  • コミュニティ
  • ブログ
  • Languages icon日本語
    • English
    • Deutsch
    • Español
    • Français
    • 한국어
    • Português (Brasil)
    • Русский
    • Українська
    • 中文
    • 繁體中文
    • 翻訳を助ける
  • GitHub

›言語の基本

はじめに

  • What & Why

セットアップ

  • インストール
  • エディタのプラグイン

言語の基本

  • 概要
  • Let Bindings
  • Primitives
  • Basic Structures
  • Types
  • Records
  • Variants
  • Options and nullability
  • Functions
  • Recursion
  • 構造化代入
  • Pattern Matching
  • Mutable Bindings
  • Loops
  • Modules

Advanced Features

  • JSX
  • External
  • 例外
  • Object

JavaScript

  • Interop
  • Syntax Cheatsheet
  • Pipe First
  • Promise
  • ライブラリ
  • JS からの変換

Extra

  • よくある質問
  • Extra Goodies
Translate

概要

この記事では Reason がもつ言語機能のほとんど全てを紹介していきます。 言語機能の詳細な説明ではなく、クイックリファレンスとして機能するようになっています。 各機能の詳細な説明は、左側のガイドをご覧ください。

Let 変数束縛

Details: Let Bindings

機能例
文字列let hi = "Hello World";
整数値let count = 42;
型註釈付きでの束縛let count: int = 42;
  • Note: Let bindings are immutable and cannot change once created.

組み込み型

Details: Primitives

機能Example
整数型let x: int = 10;
浮動小数点数型let x: float = 10.0;
真偽値型let x: bool = false;
文字列型let x: string = "ten";
文字型let x: char = 'c';
Unitlet x: unit = ();
Optionlet x: option(int) = Some(10);
タプル型let x: (int, string) = (10, "ten");
リスト型let x: list(int) = [1, 2, 3];
配列型let x: array(int) = [|1, 2, 3|];
関数型let x: (int, int) => int = (a, b) => a + b;

文字列

Details: Strings

機能例
文字列"Hello"
文字列の連結"Hello " ++ "World"
文字'x'
Character at indexlet x = "Hello"; x.[2];
  • String Functions: module String

数値

  • Details: Integer
  • Details: Float
機能例
整数23, -23
整数の演算23 + 1 - 7 * 2 / 5
整数の剰余演算13 mod 2
浮動小数点数23.0, -23.0
浮動小数点数の四則演算23.0 +. 1.0 -. 7.0 *. 2.0 /. 5.0
浮動小数点数の累乗2.0 ** 3.0

Booleans and Logical Operators

Details: Boolean

機能例
真偽値true, false
比較演算>, <, >=, <=
論理演算!, &&, &#124;&#124;
参照の等価性===, !==
構造の等価性==, !=

If-Else Expressions

機能例
If-Else expressionsif (condition) { a; } else { b; }
Ternary expressionscondition ? a : b;
  • Note: These are expressions and can be assigned to a variable: let x = if (condition) { a; } else { b; };

Functions

Details: Functions

機能例
Function definitionlet divide = (a, b) => a / b;
Function callsdivide(6, 2); // 3
Named argumentslet divide = (~a, ~b) => a / b;
Calling named argumentsdivide(~a=6, ~b=2); // 3
Named argument punningdivide(~a, ~b);
Recursive functionslet rec infinite = () => infinite();

Advanced Functions

機能例
Partial applicationlet divideTen = divide(10); divideTen(5); // 2
Partially applying out of orderlet half = divide(_, 2); half(10); // 5
Optional argumentslet print = (~prefix=?, text) => {...};
Optional arguments with defaultlet divide = (~a=100, ~b) => a / b;
Function chaining (pipe)32 &#124;> half &#124;> half; // 8

Function Types

機能例
Inline typinglet divide = (a: int, b: int): int => a / b;
Standalone typetype intFn = (int, int) => int;
Using standalone typelet divide: intFn = (a, b) => a / b;
Typing optional argumentslet print = (~prefix: option(string)=?, text) => {...};

Implicit Return

There is no return keyword in Reason. The last expression in a block or function definition is the returned value.

let twentyThree = () => {
  let x = 10;
  let x = x + 10;
  /* x + 3 is the implicit return of the function. */
  x + 3;
};

Basic Structures

Details: Basic Structures

FeatureExample
List (Immutable)[1, 2, 3]
List add to front[a1, a2, ...theRest]
List concat[a1, a2] @ theRest
Array (Mutable)[&#124;1, 2, 3&#124;]
Array accesslet arr = [&#124;1, 2, 3&#124;]; arr[1];
Tuples(1, "hello")
  • List Functions: module List
  • Array Functions: module Array

Maps and Sets

There are several different ways to interact with Maps and Sets depending on the specific environment being used. In standard Reason code there are Map and Set modules:

  • module Map.Make
  • module Set.Make

When using BuckleScript belt exposes these modules:

  • module Belt.Map
  • module Belt.Set

There are also other libraries that will provide their own implementation of these data structures. Check the style guide of the project you are working in to determine which module to use.

Type Annotations

Any expression or argument may include a "type annotation". In most cases, type annotations are not necessary and the compiler will infer the types automatically. You may include type annotations to verify your own understanding against what the compiler infers.

FeatureExample
Expression type annotationlet x = (expression: int)
Annotation on let bindinglet x: int = expression;
Argument/return value annotationlet addOne = (a: int): int => a + 1;

Type Parameters

Types can be made generic with type parameters.

FeatureExample
Type parameterstype pair('a, 'b) = ('a, 'b);
Annotation with parameterslet x: pair(int, string) = (10, "ten");
String listlet x: list(string) = ["Hello", "World"];

Records

Details: Records

FeatureExample
Record definitiontype t = {foo: int, bar: string};
Record creationlet x = {foo: 10, bar: "hello"};
Record accessx.foo;
Record spreadlet y = {...x, bar: "world"};
Destructuringlet {foo, bar} = x;
Mutable record fieldstype t = {mutable baz: int}; let z = {baz: 10};
Mutable record updatesz.baz = 23;
With type parameterstype t('a) = {foo: 'a, bar: string};
  • Note: Record types are nominal. This means that two different record definitions (type x = {...};) with the exact same fields are not compatible. They cannot be used interchangeably and cannot be spread into each other.

Variants

Details: Variants

Variant types model values that may assume one of many known variations. This feature is similar to "enums" in other languages, but each variant form may optionally specify data that is carried along with it.

FeatureExample
Variant definitiontype t = &#124; Foo &#124; Bar;
Variants with argstype t = &#124; Foo(string) &#124; Bar(int);
With type parameterstype t('a) = &#124; One('a) &#124; Two('a, 'a);
Using a variantlet x = Two("Hello", "World");

Options

Details: Options

Options are a built-in variant that represent the presence or absence of a value. It is similar to the concept of "nullable" values in other languages. Options are used often.

FeatureExample
Definition (already defined)type option('a) = &#124; None &#124; Some('a);
Value that is presentlet x = Some("Hello World");
Value that is absentlet y = None;

Pattern Matching

Pattern matching is a very powerful feature in Reason. It matches against variants and ensures all cases are covered. Start matching using the switch keyword:

switch (foo) {
| Some(value) => doSomething(value)
| None => error()
}
FeatureExample
Basic case&#124; Some(value) => doSomething(value)
When conditions&#124; Some(value) when value > 10 => doSomething(value)
Catch-all case&#124; _ => doSomething()
Matching lists&#124; [a, b, ...rest] => doSomething(rest)
Matching records&#124; {foo: value} => doSomething(value)
Matching literals&#124; "Hello" => handleHello()

Unit

The special "unit" value (written ()) represents something that never has any meaningful value (this is distinct from options which may have a value). Functions usually indicate that they perform a side effect by returning a unit value.

FeatureExample
Creating a unitlet x = ();
Passing to a functionfn(a, b, ());
Unit as only argumentlet fn = () => 1; fn();

Refs

Details: Mutable Bindings

Refs allow mutable "variables" in your program. They are a thin wrapper around a record with a mutable field called contents.

FeatureExample
Type (already defined)type ref('a) = {mutable contents: 'a};
Ref creationlet x = ref(10); or let x = {contents: 10};
Ref accessx^; or x.contents;
Ref updatex := 20; or x.contents = 20;

Loops

Details: Loops

Loops are discouraged in most cases. Instead functional programming patterns like map, filter, or reduce can usually be used in their place.

FeatureExample
Whilewhile (condition) {...}
For (incrementing)for (i in 0 to 9) {...} (inclusive)
For (decrementing)for (i in 9 downto 0) {...} (inclusive)
  • Note: There is no break or early returns in Reason. Use a ref containing a bool for break-like behavior: let break = ref(false); while (!break^ && condition) {...};

Modules

Details: Modules

Modules are a way to group types and values. Each Reason file implicitly creates a module of the same name. Each type definition and let binding in a module automatically becomes a "member" of that module which can be accessed by other modules. Modules can also be nested using the module keyword.

FeatureExample
Module creationmodule Foo = { let bar = 10; };
Module member accessFoo.bar;
Module typesmodule type Foo = { let bar: int; };

Functors

Functors are like functions that create modules. This is an advanced topic that can be very powerful. Here is a basic example:

module type Stringable = {
  type t;
  let toString: (t) => string;
};

module Printer = (Item: Stringable) => {
  let print = (t: Item.t) => {
    print_endline(Item.toString(t));
  };

  let printList = (list: list(Item.t)) => {
    list
    |> List.map(Item.toString)
    |> String.concat(", ")
    |> print_endline;
  };
};

module IntPrinter = Printer({
  type t = int;
  let toString = string_of_int;
});

IntPrinter.print(10); // 10
IntPrinter.printList([1, 2, 3]); // 1, 2, 3

Comments

FeatureExample
Multiline Comment/* Comment here */
Single line Comment// Comment here
← エディタのプラグインLet Bindings →
  • Let 変数束縛
  • 組み込み型
  • 文字列
  • 数値
  • Booleans and Logical Operators
  • If-Else Expressions
  • Functions
    • Advanced Functions
    • Function Types
  • Implicit Return
  • Basic Structures
  • Maps and Sets
  • Type Annotations
  • Type Parameters
  • Records
  • Variants
  • Options
  • Pattern Matching
  • Unit
  • Refs
  • Loops
  • Modules
  • Functors
  • Comments