デフォルトハンドラ
💡 お知らせ: このドキュメントはAIによって翻訳されています。表現に違和感がある場合は、原文(英語)を参照するか、翻訳にご協力ください。
Flix は デフォルトハンドラ(default handler) をサポートしています。これは、
エフェクトが、そのエフェクトを IO エフェクトへと変換するハンドラを宣言できる
ことを意味します。これにより、main(および @Test が付与された任意のメソッド)は、
run-with ブロックでハンドラを明示的に提供することなく、そのエフェクトを
使えるようになります。
たとえば、次のように書けます。
use Sys.Env
use Time.Clock
def main(): Unit \ {Clock, Env, Logger} =
let ts = Clock.currentTime(TimeUnit.Milliseconds);
let os = Env.getOsName();
Logger.info("UNIX Timestamp: ${ts}");
Logger.info("Operating System: ${os}")
これを Flix コンパイラは次のように変換します。
use Sys.Env
use Time.Clock
def main(): Unit \ IO =
run {
let ts = Clock.currentTime(TimeUnit.Milliseconds);
let os = Env.getOsName();
Logger.info("UNIX Timestamp: ${ts}");
Logger.info("Operating System: ${os}")
} with Clock.runWithIO
with Env.runWithIO
with Logger.runWithIO
すなわち、Flix コンパイラは Clock.runWithIO、Env.runWithIO、
Logger.runWithIO の呼び出しを自動的に挿入します。これらは、それぞれの
エフェクトに対するデフォルトハンドラです。
たとえば、Clock.runWithIO は次のように宣言されています。
use Time.Clock
@DefaultHandler
pub def runWithIO(f: Unit -> a \ ef): a \ (ef - Clock) + IO = ...
デフォルトハンドラは @DefaultHandler アノテーションを使って宣言します。
各エフェクトが持てるデフォルトハンドラは高々 1 つであり、それはそのエフェクトの
コンパニオンモジュール(companion module)の中になければなりません。
デフォルトハンドラは、次の形式のシグネチャを持たなければなりません。
def runWithIO(f: Unit -> a \ ef): a \ (ef - E) + IO
ここで E はエフェクトの名前です。
デフォルトハンドラを持つエフェクトは、テストの中で使えます。たとえば:
@Test
def myTest01(): Unit \ {Assert, Logger} =
Logger.info("Running test!");
Assert.assertEq(expected = 42, 42)