3

私はいくつかのErlangを学び始めましたが、現在、次の「問題」に悩まされています。

私は再帰がどのように機能するかを知っており、HigherOrderFunctions の基本を認識しています。

したがって、全体の概念をさらに理解するために、fold を使用して "lists:all/2" を実装しました。

fold(_, Start, []) -> Start;
fold(F, Start, [H|T]) -> fold(F, F(H, Start), T).

all(Pred, L) ->
    F = fun(H, ToF) ->
        case Pred(H) of
            true -> ToF;
            false -> false
        end
    end,
    fold(F, true, L).

このバージョンが空のリストを気にしないことは知っていますが、それが私を悩ませているわけではありません。なぜそれがどのように機能するのかわかりません。

リスト [1,2,3] を使用して Pred を "fun(X) when X == 3 -> true; (_) -> false end" に設定すると、明らかに "false" が返されます。しかし、なぜ?何かが返される前の最後の呼び出しとして紙の上でこれを処理すると、次のようになります。

fold(F, F(H, Start), T)

ここで、F は Pred であり、F(H, Start) は「true」を返します。これは、最後の要素が 3 であり、T が空のリスト [] であるためです。

したがって、これを正しく行うと、最後の呼び出しは fold(_, true, []) である必要があり、したがって「true」を返す必要がありますが、そうではありません。

ここで何かが足りないのでしょうか、それとも最後の式の評価に関して何か間違っていますか? この関数は、「Pred」のすべての戻り値に対して何らかの論理 AND を使用していますか?

4

2 に答える 2

4

基本的に、最後の呼び出しについては正しいですが、分析を行うときは、値を代入trueしましStartた。実際、この値はfalse次のとおりです。

fold(F, true, [1,2,3])

次のように評価されます。

fold(F, true, [1|[2,3]]) -> fold(F, F(1, true), [2,3])

これは次のように評価されます。

fold(F, false, [2|3]) -> fold(F, F(2, false) [3])

これは次のように評価されます。

fold(F, false, [3|[]]]) -> fold(F, F(3, false), [])

これは次のように評価されます。

fold(_, false, []) -> false

最後の呼び出しPredで true が返されるToFため、これは false です。

于 2012-09-21T10:18:10.417 に答える
2

単純な問題に対する複雑な解決策は避けるようにしてください(コードのコンパクトさは関数型言語の利点の 1 つです)。

all(_, []) ->
   true;
all(Pred, [H|T]) ->
   case Pred(H) of
      true ->
         all(Pred, T);
      false ->
         false
   end.
于 2012-09-21T10:30:06.113 に答える