本日翻訳したCurryチュートリアルより:
3.5.4 非決定論的関数
関数はさらに非決定論的にも書けます。非決定論的「関数」は、数学での関数とは意味が違ってきます。なぜなら複数の違う値を、同じ入力に対して返すことがあるからです。たとえば病院の案内システムとして、医者がどの日に待機しているかというのを非決定論的関数で書くと:
oncall Joan = Monday oncall Joan = Wednesday oncall Richard = Monday oncall Luc = Tuesday ...“oncall Joan”の値は“Monday”か“Wednesday”になりますが、どちらが計算されるかプログラマは選べません。非決定論的関数では論理プログラミングと同様のスタイルをとることができますが、関数型プログラミングの利点である、入れ子の式や遅延評価なども使うことができます。とくに、ふつうの関数の評価に関するいくつかの強い特徴は、非決定論関数でも有効です。たとえば、“today”にきょうの曜日が入っているとして、引数として与えた医者が、現在診察できる(available)かどうかをあらわす述語“available”を書いてみます:
available x | oncall x == today = True | otherwise = False非決定論的な機能がなければ、“oncall”のコードは何らかのデータ構造、つまり医者が待機している日のリストかなにかを必要とするでしょうし、“available”の構造はもっと複雑になったでしょう。
非決定論はパワフルな特徴ですが、プログラミングでも、他の行為と同じように、パワーを扱うにはそれなりの注意が必要です。非決定論的なプログラムは、あり得るすべての出力が、すべて同じように必要になるようなときに使うべきです。
特定の出力がとくに重要だという場合、プログラムは(より)決定論的な性質を持ちます。このような場合も非決定論的な機能は便利でしょうが、ふさわしい結果を必要な順番にしたがって選ぶプログラムを通して、内部的に使うようにします。めちゃくちゃ初歩だけどな…。
(そういえば、これガードのインデントがそろってないけど、これでいいんでしたっけ…?)