エラー メッセージを引用したり、使用しているコンパイラを指定したりしません。SML/NJ から得たものは次のとおりです。
3867615/john316.sml:7.25-7.64 Error: operator and operand don't agree [tycon mismatch]
operator domain: int list
operand: int
in expression:
answer x
3867615/john316.sml:7.25-7.64 Error: operator and operand don't agree [circularity]
operator domain: 'Z * 'Z list
operand: 'Z * 'Z
in expression:
(findAll f) l :: (findAll f) r
3867615/john316.sml:7.25-7.64 Error: argument of raise is not an exception [tycon mismatch]
raised: _ list
in expression:
raise (answer x :: (findAll <exp>) l :: (findAll <exp>) r)
3867615/john316.sml:9.9-9.37 Error: operator and operand don't agree [circularity]
operator domain: 'Z * 'Z list
operand: 'Z * 'Z
in expression:
(findAll f) l :: (findAll f) r
最初のエラーはかなり明白です:は引数answer
を期待するように宣言されていますが、 a から来るan を使用し、でなければなりません。3 番目のエラーは、おそらく優先順位の問題です。コンパイラが式をどのように解析したかがわかりますが、これはおそらく意図したものではありません。(しかし、以下で説明するように、あなたが意図したことは意味がありません。)int list
answer x
x
Node
int
::
2 番目と 4 番目のエラーは、リストの先頭に要素を追加する ("cons") コンストラクターと、@
2 つのリストを連結する ("append") 演算子を混同したことが原因です。
ここで、例外に戻りanswer
ます。それはなんのためですか?関数はすべての出現箇所を見つける必要があるため、ツリー全体をトラバースする必要があります。あなたが早く帰らなければならない状況はありません。したがって、例外は必要ありません。あなたは基本的に正しいアルゴリズムを持っています (空のツリーでは、一致がないので空のリストを返します。ノードでは、存在する場合は再帰呼び出しの結果に一致を追加します)、物事を複雑にしないでください。
2 つの修正を行うと、次のコードが得られます (コンパイルされます)。
fun findAll f Empty = []
| findAll f (Node(x, l, r)) =
if f x then x :: findAll f l @ findAll f r
else findAll f l @ findAll f r