Mercury 勉強メモ

関数論理型言語 Mercury を勉強するブログです.

Mercury 入門 (7) 高階関数,高階述語

高階述語

入門 (6) で出てきたは,引数で述語を受け取る述語でした. このように述語を引数で受け取る述語のことを高階述語とよびます.

solutions/2の宣言は以下のようになっています.

:- pred solutions(pred(T), list(T)).
:- mode solutions(pred(out) is multi, out(non_empty_list)) is det.
:- mode solutions(pred(out) is nondet, out) is det.

ここでは,pred(T)が引数の述語の型を,pred(out) is multiの部分が 引数の述語のモードを表しています. (out(non_empty_list)は別の場所で説明します.制約のついたモードだと思ってください.)

ここでは,

pred(int::in, int::out) is det

という述語を受け取って,この述語に整数を2回通したときの値を返す述語, doublep/3を定義して使う例を示します.

プログラム

実行結果

40

高階関数

高階述語と同じように高階関数も利用可能です. int を受け取って int を返す関数の型は,

func(int) = int

と書きます.以下は,このような関数を受け取って2回適用する 述語doublefの例です.

プログラム

実行結果

40

ラムダ式 (無名述語,無名関数)

名前のない述語や関数のことをMercuryではラムダ式と呼びます. ラムダ式は,高階述語や高階関数の引数として, わざわざ独立して定義するまでもない,小さな関数や述語を渡すときに便利です.

無名述語は,

pred(X::in, Y::out) is det :- Y = X * 2

無名関数は,

func(M) = M * 2

のように書き表します.以下にプログラム例を示します.

実行結果

40
40