2
    let rec remove x = function
        y :: l when x = y -> l
       |y :: l (* x <> y *) -> y :: remove x l
       |[] -> []

この本には、この関数には問題があると書かれています。要素が見つからない場合、リスト全体が不必要にコピーされます。したがって、次の改善されたバージョンが提供されます。

    exception Unchanged

    let rec remove_inner x = function
        y :: l when x = y ->
            l
       |y :: l ->
            y :: remove_inner x l
       |[] -> 
        raise Unchanged

    let remove x l =
        try remove_inner x l with
            Unchanged ->
                l

ここのポイントがよくわかりません。

4

2 に答える 2

0

y :: remove x lは、コピーが発生する場所です。これ::は、リスト要素の [中置演算子] コンストラクターが組み込まれているためです。

remove関数の単純なバージョンでは、演算子を使用して、引数::に相当する最初の要素を除く元のリストのすべての要素を持つ新しいリストを作成します。x元のリストにそのような要素がなかった場合でも、新しいリストが作成され、元のリストと同等のコピーになります。

関数の「改善された」バージョンは、要素を削除せずに元のリストの最後に到達したときに例外を発生させるremove別の関数を呼び出します。外側の関数は、例外をキャッチすると元のリストを返します。remove_innerUnchangedremoveUnchanged

于 2013-10-08T21:28:15.020 に答える