Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Console

💡 お知らせ: このドキュメントはAIによって翻訳されています。表現に違和感がある場合は、原文(英語)を参照するか、翻訳にご協力ください。

Flix は、ターミナル I/O のためのライブラリエフェクトとして Console を提供しています。Console エフェクトにはデフォルトハンドラがあるため、main の中で明示的に runWithIO を呼び出す必要はありません。主要なモジュールは Sys.Console です。

Console エフェクト

Console エフェクトは5つの操作を持ちます。1つは標準入力から1行を読み取り、残りの4つは標準出力または標準エラー出力へ文字列を書き込みます:

pub eff Console {
    /// コンソールから 1 行を読み取ります。
    /// 入力の終端に達した場合は `None` を返します。
    def readln(): Option[String]

    /// 与えられた文字列 `s` を標準出力に書き込みます。
    def write(s: String): Unit

    /// 与えられた文字列 `s` を標準出力に書き込み、続けて改行を書き込みます。
    def writeLine(s: String): Unit

    /// 与えられた文字列 `s` を標準エラー出力に書き込みます。
    def writeErr(s: String): Unit

    /// 与えられた文字列 `s` を標準エラー出力に書き込み、続けて改行を書き込みます。
    def writeErrLine(s: String): Unit
}

これらの操作はハンドラが実装するインターフェースです。プログラムがこれらを直接呼び出すことはほとんどありません。代わりに、これらの操作をもとに定義された Console モジュールの関数を呼び出します。

Console モジュール

Console エフェクトは Sys.Console モジュールのコンパニオンであり、このモジュールは出力用の関数といくつかのプロンプト用関数を提供します:

mod Sys.Console {
    /// `x` の文字列表現を標準出力に出力します。
    def print(x: a): Unit \ Console with ToString[a]

    /// `x` の文字列表現を標準出力に出力し、続けて改行を出力します。
    def println(x: a): Unit \ Console with ToString[a]

    /// `x` の文字列表現を標準エラー出力に出力します。
    def eprint(x: a): Unit \ Console with ToString[a]

    /// `x` の文字列表現を標準エラー出力に出力し、続けて改行を出力します。
    def eprintln(x: a): Unit \ Console with ToString[a]

    /// プロンプト `p` を出力して 1 行を読み取り、入力に `f` を適用します。
    /// `Err(msg)` の場合は `msg` を出力して再度プロンプトを表示し、`Ok(v)` の場合は `Some(v)` を返します。
    /// 入力の終端に達した場合は `None` を返します。
    def readlnWith(p: a, f: String -> Result[String, b]): Option[b] \ Console with ToString[a]

    /// プロンプト `p` を出力して 1 行を読み取り、`b` 型の値としてパースします。
    /// パースできない場合はエラーを出力して再度プロンプトを表示します。
    /// 入力の終端に達した場合は `None` を返します。
    def readlnAs(p: a): Option[b] \ Console with ToString[a], FromString[b]

    /// yes/no のヒント付きでプロンプト `p` を出力し、ブール値の回答を読み取ります。
    /// 入力が空の場合は `default` を返します。"y"、"yes"、"n"、"no" 以外の入力の場合は
    /// エラーを出力して再度プロンプトを表示します。
    def confirm(p: a, default: {default = Bool}): Bool \ Console with ToString[a]
}

操作とは異なり、print、println、eprint、eprintln は String だけでなく、ToString のインスタンスを持つあらゆる値を受け取ります。

基本的なコンソール I/O

Console の最もシンプルな使い方は、プロンプトを出力し、入力を読み取り、応答することです。readln は入力の終端で None を返すため、プログラムはその結果をパターンマッチします:

use Sys.Console

def main(): Unit \ Console =
    Console.print("What is your name? ");
    match Console.readln() {
        case Some(name) => Console.println("Hello ${name}!")
        case None       => Console.println("No name given.")
    }

値の出力

出力用の関数は ToString のインスタンスを持つあらゆる値を受け取るため、値をあらかじめ String に変換する必要はありません。print と eprint は末尾に改行を付けずに書き込み、println と eprintln は改行を付け加えます。eprint と eprintln は標準エラー出力に書き込みます:

use Sys.Console

def main(): Unit \ Console =
    let o = Some(123);
    let l = 1 :: 2 :: 3 :: Nil;
    Console.print("o = ");
    Console.println(o);
    Console.print("l = ");
    Console.println(l);
    Console.eprint("sum = ");
    Console.eprintln(List.sum(l))

このプログラムは標準出力に o = Some(123) と l = 1 :: 2 :: 3 :: Nil を、標準エラー出力に sum = 6 を出力します。

確認付き入力

Console.confirm 関数は yes/no の質問をして Bool を返します。プロンプトの後ろにはデフォルト値を示す [Y/n] または [y/N] というヒントが続き、これはユーザーが何も入力せずに Enter を押した場合に使われます。y、yes、n、no(大文字・小文字を区別しない)以外の回答を入力した場合はエラーを出力して再度プロンプトを表示します。入力の終端に達した場合はデフォルト値が返されます:

use Sys.Console

def main(): Unit \ Console =
    let proceed = Console.confirm("Deploy to production?", default = true);
    if (proceed)
        Console.println("Deploying...")
    else
        Console.println("Aborted.")

バリデーション付き入力

Console.readlnWith 関数は、入力がバリデータを通過するまで繰り返しユーザーにプロンプトを表示します。バリデータは、成功時には Ok(value) を返し、メッセージを出力して再度プロンプトを表示させるには Err(message) を返します。入力が通過する前に入力の終端に達した場合、結果は None になります:

use Sys.Console

def main(): Unit \ Console =
    let n = Console.readlnWith(
        "Enter a number (1-10): ",
        s -> match Int32.fromString(s) {
            case Some(i) if i >= 1 and i <= 10 => Ok(i)
            case _                             => Err("Please enter a number between 1 and 10.")
        }
    );
    match n {
        case Some(i) => Console.println("You entered: ${i}")
        case None    => Console.println("No number given.")
    }

パース付き入力

Console.readlnAs 関数は、FromString のインスタンスを持つ任意の型の値を求めるプロンプトを表示します。入力行をトリムしてパースし、パースできる行が得られるまで再度プロンプトを表示します。パースする型は、型注釈または結果の使われ方によって決まります:

use Sys.Console

def main(): Unit \ Console =
    let n: Option[Int32] = Console.readlnAs("Enter an integer: ");
    match n {
        case Some(i) => Console.println("${i} squared is ${i * i}.")
        case None    => Console.println("No integer given.")
    }