ATS では、高階関数の使用の多くは関数テンプレートによって容易に置き換えできます。 特に、高階関数は対応する関数テンプレートを元に実装されることもしばしばです。 実際の例を最初に見てみましょう。 次のコードは、高階関数テンプレートとしてのリストのマップの一般的な実装です:
// extern fun {a:t@ype} {b:t@ype} list_map_fun{n:nat} (xs: list(a, n), f: a -> b): list_vt(b, n) // implement {a}{b} list_map_fun (xs, f) = let // fun aux{n:nat} (xs: list(a, n)): list_vt(b, n) = ( case+ xs of | list_nil () => list_vt_nil () | list_cons (x, xs) => list_vt_cons (f(x), aux(xs)) ) // in aux(xs) end // end of [list_map_fun] //
// extern fun {a:t@ype} {b:t@ype} list_map_cloref{n:nat} (xs: list(a, n), f: a -<cloref1> b): list_vt(b, n) //
リストのマップを実装する正当な方法は (私の知るかぎり) 次のようなものです:
// extern fun {a:t@ype} {b:t@ype} list_map{n:nat} (xs: list(a, n)): list_vt(b, n) // extern fun {a:t@ype}{b:t@ype} list_map$fopr(x: a): b // implement {a}{b} list_map (xs) = let // fun aux{n:nat} (xs: list(a, n)): list_vt(b, n) = ( case+ xs of | list_nil () => list_vt_nil () | list_cons (x, xs) => list_vt_cons (list_map$fopr<a><b>(x), aux(xs)) ) (* end of [aux] *) // in aux(xs) end // end of [list_map] //
list_map を用いて、list_map_fun と list_map_cloref の両方を次のようにそのまま実装できます:
implement {a}{b} list_map_fun(xs, f) = let // implement list_map$fopr<a><b> (x) = f(x) // in list_map<a><b> (xs) end // end of [list_map_fun] (* ****** ****** *) implement {a}{b} list_map_cloref(xs, f) = let // implement list_map$fopr<a><b> (x) = f(x) // in list_map<a><b> (xs) end // end of [list_map_cloref]
この章で紹介したコード全体とテストコードを含む list_map.dats ファイルはオンラインから入手できます。