あなたの試みにはいくつかの間違いがあります:
- パラメータ。があります
zipWith xs ys
が、タイプは最初のパラメーターが関数でなければならないことを示しているので、それを に変更しzipWith f xs ys
ます。
- zipWith を再帰的に呼び出しています。ただし、ListPair.foldr がそれを処理してくれるので、そうしないでください。
- ListPair.foldr 0 を開始値として指定しています。折り畳み関数は常に戻り値と同じ型の開始値を取ります- zipWith がリストを返すようにしたいので、折り畳み関数は開始値としてリストを取る必要があります。つまり、空のリストです。
ListPair.foldr がどのように機能するかを考えてみてください。一度に 1 つのパラメーターを実行できます。ListPair.foldr のタイプは次のとおりです。
fn : ('a * 'b * 'c -> 'c) -> 'c -> 'a list * 'b list -> 'c
最初のパラメーターは次のタイプの関数です。
fn : 'a * 'b * 'c -> 'c
例としておもちゃの関数を作ってみましょう:
fun foo (a, b, acc) = a+b :: acc
この関数は、2 つの数値とリストを受け取り、2 つの数値を加算してリストの前に配置し、それを返します。タイプは次のとおりです。
fn : int * int * int list -> int list
これは、ListPair.foldr の最初のパラメーターの型シグネチャにうまく対応しています。
では、型を見てみましょうListPair.foldr foo
。
fn : int list -> int list * int list -> int list
次のパラメータは int リストで、折り畳みの開始値です。これが空のリストであることはすでにわかっています。のタイプListPair.foldr foo []
は次のとおりです。
fn : int list * int list -> int list
最後のパラメーターは、2 つのリストを含むタプルです。ランダムなリストをいくつか入れて、sml インタープリターで試してみます。
- ListPair.foldr foo [] ([1,2,3],[10,20,30])
> val it = [11, 22, 33] : int list
あとは、ListPair.foldr のパラメーター (foo と 2 つのランダム リスト) を zipWith のパラメーターに置き換えるだけで完了です。