0

個人的な言語を erlang にコンパイルしようとしています。句にパターン マッチングを使用する関数を作成したいと考えています。

これは私のデータです:

Data =
    [ {a, <a_body> }
    , {b, <b_body> }
    , {c, <c_body> }
    ].

これは私が欲しいものです:

foo(a) -> <a_body>;
foo(b) -> <b_body>;
foo(c) -> <c_body>;
foo(_) -> undefined. %% <- this

私は現時点でそれを行います:

MkCaseClause =
    fun({Pattern,Body}) ->
        cerl:c_clause([cerl:c_atom(Pattern)], deep_literal(Body))
    end,
WildCardClause = cerl:c_clause([ ??? ], cerl:c_atom(undefined)),
CaseClauses = [MkCaseClause(S) || S <- Data] ++ [WildCardClause],

だから私が定義するのを手伝ってくださいWildCardClause。コンパイル済みの関数を a も b も c も指定せずに呼び出すと、結果が** exception error: no true branch found when evaluating an if expression in function ....

Core Erlang コードを印刷すると、次のようになります。

'myfuncname'/1 =
    fun (Key) ->
        case Key of
          <'a'> when 'true' -> ...
          <'b'> when 'true' -> ...
          <'c'> when 'true' -> ...
        end

さて、コアがコンパイルされたときにcase変換されます。ifしたがって、純粋なワイルドカードを取得するにtrueは、式のように句を指定する必要があります。式と式の一致はセマンティクスが異なるifため、その方法がわかりません。場合によっては、ワイルドカードではありません。trueifcasetrue

そして、のように内部にワイルドカードを含む式を一致させたい場合はどうすればよいでしょうか{sometag,_,_,Thing} -> {ok, Thing}

ありがとうございました

4

1 に答える 1

0

私はこれを行う方法を見つけました

...
WildCardVar = cerl:c_var('_Any'),
WildCardClause = cerl:c_clause([WildCardVar], cerl:c_atom(undefined)),
...

内側のワイルドカードでも機能するはずですが、ワイルドカードごとに異なる変数名を付けるように注意する必要があります。_複数の変数のみ_が互いに一致しないためです。

f(X,_, _ ) %% matches f(a,b,c)
f(X,_X,_X) %% doesn't
于 2013-07-18T14:48:27.923 に答える