1

Rascal コードで頻繁に発生するアクティビティのように見える型キャストを行う関数を作成しようとしています。しかし、私はそれを正しく理解できないようです。次のいくつかのバリエーションは失敗します。

public &T cast(type[&T] tp, value v) throws str {
    if (tp tv := v)
        return tv;
    else
        throw "cast failed";
}

誰かが私を助けることができますか?

いくつかの詳細情報: 式が特定の型を持っていることを Rascal に伝えるために、"Type Var" 形式のパターンに対して (つまり、変数宣言に対して) パターン マッチングを頻繁に使用します。

map[str,value] m := myexp

これは通常、myexp が map[str,value] 型を持っていることを知っている場合ですが、マッチングを省略すると、Rascal の型チェック メカニズムに問題が発生します。間違いに対してもう少し防御的になるために、私は通常、マッチングが失敗した場合に例外が発生する if-then-else でマッチング構造をラップします。

if (map[str,value] m := myexp) {
  // use m
} else {
  throw "cast failed";
}

代わりに書くことができるように、一般的に仕事をする単一の関数を使用して、そのような同様のコードをすべて短縮したいと思います。

cast(#map[str,value], myexp)

PS。Rascal で値型を Map にキャストする方法も参照してください。

4

2 に答える 2

1

本当にこれを行う必要がある場合、これを書く最良の方法は次のようです。

public map[str,value] cast(map[str,value] v) = v;
public default map[str,value] cast(value v) { throw "cast failed!"; }

次に、あなたはただ言うことができます

m = cast(myexp);

そして、それはあなたがやりたいことをします-実際のパターンマッチングはcast、使用したいタイプに固有のケースと、他の方法では一致しないすべてを処理するケースを使用して、 の関数シグネチャに移動されます。

valueただし、ここ(マップ内)またはリンクされた質問でtype を使用している理由はまだわかりません。複数の選択肢から 1 つを選択できるケースを処理する "標準的な" Rascal の方法は、ユーザー定義のデータ型とコンストラクターを使用してこれらを定義することです。次に、パターン マッチングを使用してコンストラクターを照合するか、isandhasキーワードを使用して値を調べて、特定のコンストラクターを使用して作成されたかどうか、または特定のフィールドがあるかどうかをそれぞれ確認できます。フィールドのルールは、特定の ADT のコンストラクター定義内のフィールドのすべてのオカレンスが同じ型を持つことです。castしたがって、この定義が最適なオプションであるかどうか、または問題に対するより良い解決策があるかどうかを確認するために、使用シナリオについて詳しく知ることが役立つ場合があります。

編集済み

JSON を読んでいる場合、それを行う別の方法は、ライブラリのその部分にもある JSON 文法と AST を使用することです (使用しているものは、現在のテキスト リーダーやライターですが、確認するにはコードをもっと見る必要があります)。次に、次のようなことを行うことができます (結果のアイデアを提供するために長い出力が含まれています)。

rascal>import lang::json::\syntax::JSON;
ok

rascal>import lang::json::ast::JSON;
ok

rascal>import lang::json::ast::Implode;
ok

ascal>js = buildAST(parse(#JSONText, |project://rascal/src/org/rascalmpl/library/lang/json/examples/twitter01.json|));
Value: object((
    "since_id":integer(0),
    "refresh_url":string("?since_id=202744362520678400&q=amsterdam&lang=en"),
    "page":integer(1),
    "since_id_str":string("0"),
    "completed_in":float(0.058),
    "results_per_page":integer(25),
    "next_page":string("?page=2&max_id=202744362520678400&q=amsterdam&lang=en&rpp=25"),
    "max_id_str":string("202744362520678400"),
    "query":string("amsterdam"),
    "max_id":integer(202744362520678400),
    "results":array([
        object((
            "from_user":string("adekamel"),
            "profile_image_url_https":string("https:\\/\\/si0.twimg.com\\/profile_images\\/2206104506\\/339515338_normal.jpg"),
            "in_reply_to_status_id_str":string("202730522013728768"),
            "to_user_id":integer(215350297),
            "from_user_id_str":string("366868475"),
            "geo":null(),
            "in_reply_to_status_id":integer(202730522013728768),
            "profile_image_url":string("http:\\/\\/a0.twimg.com\\/profile_images\\/2206104506\\/339515338_normal.jpg"),
            "to_user_id_str":string("215350297"),
            "from_user_name":string("nurul amalya \\u1d54\\u1d25\\u1d54"),
            "created_at":string("Wed, 16 May 2012 12:56:37 +0000"),
            "id_str":string("202744362520678400"),
            "text":string("@Donnalita122 @NaishahS @fatihahmS @oishiihotchoc @yummy_DDG @zaimar93 @syedames I\'m here at Amsterdam :O"),
            "to_user":string("Donnalita122"),
            "metadata":object(("result_type":string("recent"))),
            "iso_language_code":string("en"),
            "from_user_id":integer(366868475),
            "source":string("<a href="http:\\/\\/blackberry.com\\/twitter" rel="nofollow">Twitter for BlackBerry\\u00ae<\\/a>"),
            "id":integer(202744362520678400),
            "to_user_name":string("Rahmadini Hairuddin")
          )),
        object((
            "from_user":string("kelashby"),
            "profile_image_url_https":string("https:\\/\\/si0.twimg.com\\/profile_images\\/1861086809\\/me_beach_normal.JPG"),
            "to_user_id":integer(0),
            "from_user_id_str":string("291446599"),
            "geo":null(),
            "profile_image_url":string("http:\\/\\/a0.twimg.com\\/profile_images\\/1861086809\\/me_beach_normal.JPG"),
            "to_user_id_str":string("0"),
            "from_user_name":string("Kelly Ashby"),
            "created_at":string("Wed, 16 May 2012 12:56:25 +0000"),
            "id_str":string("202744310872018945"),
            "text":string("45 days til freedom! Cannot wait! After Paris: London, maybe Amsterdam, then southern France, then CANADA!!!!"),
            "to_user":null(),
            "metadata":object(("result_type":string("recent"))),
            "iso_language_code":string("en"),
            "from_user_id":integer(291446599),
            "source":string("<a href="http:\\/\\/mobile.twitter.com" rel="nofollow">Mobile Web<\\/a>"),
            "id":integer(202744310872018945),
            "to_user_name":null()
          )),
        object((
            "from_user":string("johantolsma"),
            "profile_image_url_https":string("https:\\/\\/si0.twimg.com\\/profile_images\\/1961917557\\/image_normal.jpg"),
            "to_user_id":integer(0),
            "from_user_id_str":string("23632499"),
            "geo":null(),
            "profile_image_url":string("http:\\/\\/a0.twimg.com\\/profile_images\\/1961917557\\/image_normal.jpg"),
            "to_user_id_str":string("0"),
            "from_user_name":string("Johan Tolsma"),
            "created_at":string("Wed, 16 May 2012 12:56:16 +0000"),
            "id_str":string("202744274050236416"),
            "text":string("RT @agerolemou: Office space for freelancers in Amsterdam http:\\/\\/t.co\\/6VfHuLeK"),
            "to_user":null(),
            "metadata":object(("result_type":string("recent"))),
            "iso_language_code":string("en"),
            "from_user_id":integer(23632499),
            "source":string("<a href="http:\\/\\/itunes.apple.com\\/us\\/app\\/twitter\\/id409789998?mt=12" rel="nofollow">Twitter for Mac<\\/a>"),
            "id":integer(202744274050236416),
            "to_user_name":null()
          )),
        object((
            "from_user":string("hellosophieg"),
            "profile_image_url_https":string("https:\\/\\/si0.twimg.com\\/profile_images\\/2213055219\\/image_normal.jpg"),
            "to_user_id":integer(0),
            "from_user_id_str":string("41153106"),
            "geo":null(),
            "profile_image_url":string("http:\\/\\/a0.twimg.com\\/profile_images\\/2213055219\\/image_normal.jp...

rascal>js is object;
bool: true

rascal>js.members<0>;
set[str]: {"since_id","refresh_url","page","since_id_str","completed_in","results_per_page","next_page","max_id_str","query","max_id","results"}

rascal>js.members["results_per_page"];
Value: integer(25)

次に、 で定義された型に対してパターン マッチングを使用して、lang::json::ast::json必要な情報を抽出できます。

于 2014-05-19T15:44:20.027 に答える
0

コードにバグがあります。これは固定コードです:

public &T cast(type[&T] tp, value v) throws str {
    if (&T tv := v)
        return tv;
    else
        throw "cast failed";
}

これを標準ライブラリに含めたくないことに注意してください。むしろ、必要なケースを収集し、別の方法で修正する方法を見つけてください。

このキャストが頻繁に必要な場合は、パターンベースのディスパッチなど、Rascal の優れた部分を避けている可能性があります。Mark Hills による回答も参照してください。

于 2014-05-20T08:54:11.453 に答える