再帰的な ADT がある場合
data MyType = A | B | C MyType | D MyType MyType
のインスタンスに次のようなものがMyType
含まれているかどうかを判断する関数を作成できます。A
hasA :: MyType -> Bool
hasA A = True
hasA B = False
hasA (C x) = hasA x
hasA (D x y) = (hasA x) || (hasA y)
これは非環式のインスタンスでは機能しますが、環式構造では停止しません。
let x = C x in hasA x
代わりに、この例では を返す必要がありFalse
ます。他の場合 ( を使用D
) では、 を返す代わりに誤って停止しませんでしたTrue
。
hasA
では、問題は、循環構造で機能するような関数を最も簡単に作成するにはどうすればよいかということです。Racketには の形式で特に優れた機能があり、追加のコードをほとんど使用せずに、上記の例のようにdefine/fix
関数hasA
を意図したとおりに動作させ、構造を返すことができます。False
Haskellで似たようなことをする方法はありますか? 拡張機能はありますか?
編集:define/fix
実際には、Matt Might によって作成されたマクロであり、組み込み機能ではなく、Racket のメタプログラミング機能を利用していることがわかりましたが、これにより、Racket の優れた機能が失われることはありません。このマクロは Haskell で再現できるのでしょうか?