問題タブ [partial-functions]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
idris - Idris: 関数は Nat パラメーターで機能し、Integer パラメーターでの型チェックに失敗します
私はイドリスが初めてです。私は型を実験していますが、私の仕事は「タマネギ」を作ることです.2つの引数を取る関数です:数値と何でも、List
ネストされた回数に何でも入れます。
たとえば、 の結果は にmkOnion 3 "Hello World"
なります[[["Hello World"]]]
。私はそのような関数を作成しました、これは私のコードです:
プログラム作業の結果:
これはまさに私が必要とするものです。しかし、私が同じことをすると、このようにNatをIntegerに変更します
エラーが発生します:
型チェックが失敗するのはなぜですか?
Integer
これは、負の値をとることができ、Type
負の値の場合は計算できないためだと思います。私が正しければ、コンパイラはこれをどのように理解しますか?
scala - 部分機能の結合
私は Java 出身で、次のような 2 つの部分関数を組み合わせたいと考えています。
私はこのようなものを書きたい:
しかし、コンパイルを拒否します。簡潔に修正する方法はありますか?
scala - Scala マクロを使用して新しい部分関数を作成または変換する方法は?
特定の部分関数を変換して新しい部分関数を作成するマクロを作成するのに問題があります。たとえば、指定された部分関数をその要素 (パターン バインダー、ガード条件、ボディ) に分解できるようにしたいと考えています。次に、パターン バインダーとガード条件を小さな断片に分解し、これらの断片から新しい部分関数を再構築します。しかし、デバッグできないマクロ展開で奇妙なエラーが発生します。
同じエラーを引き起こす最も単純な問題は、指定された部分関数をバインダー、ガード、および本体に分解し、それを同じ部分関数に再アセンブルするコードです。
単純な型ではこれを行うことができますPartialFunction[Int,Any]
が、ケース クラスを含む型ではできませんPartialFunction[MyCaseClass,Any]
。
動作するコードと動作しないコードを次に示します。
作業コード: 部分関数を取得し、準引用符を使用してそれを分解し、同じ関数を再度アセンブルして返します。
このマクロは、コンパイルしてテストに合格します。
Non-working codeInt
:部分関数の引数としての代わりにケース クラスを使用することを除いて、まったく同じマクロです。
コードはまったく同じで、タイプが異なるだけです (Complicated
ではなくSimple
)。
マクロ コードはコンパイルされますが、テストはコンパイルに失敗します (マクロ展開で失敗します)。
問題を可能な限り最小限に単純化しましたが、それでも失敗します。私の実際のコードでは、型はより複雑で、部分関数にはガードがある場合があり、引数とガードを再配置することで部分関数のコードを変換します。ガードがない場合は変換を機能させることができますが、部分関数の引数がケース クラスの場合は機能しません。おそらく、ガードの存在は問題の根源ではありません。問題は、unapply
どこかに複合型がある場合に発生します。上記の非常に単純化された例で得られるのと本質的に同じエラー メッセージが表示されます。
部分関数を変換する多くの代替方法を試したにもかかわらず、この問題を解決できないようです。
- ホワイトボックス マクロ コンテキストを使用する
- 上記の例のように、プレーンな準引用符を使用します
- ケースとパターン
cq"..."
には特別な準引用符を使用し、準引用符のドキュメントに示されているようにpq"..."
q"{case ..$cases}"
- guard: とのマッチング
q"{case $binder if $guard => $body }"
、またcq
およびpq
quasiquotesとのマッチング c.typecheck
orをさまざまな場所に追加するc.untypecheck
(これは以前は と呼ばれていましresetAllAttrs
たが、現在は廃止されています)- 準引用符は使用しませんが、生の構文ツリーですべてを行います:
Traverser
生のツリー マッチングと共に使用case UnApply(Apply(Select(t@Ident(TermName(_)), TermName("unapply")), List(Ident(TermName("<unapply-selector>")))), List(binder)) if t.tpe <:< typeOf[Blob]
します。 Ident
パターン マッチャーの をガード条件から取得したに置き換えてみてくださいIdent
。また、その逆も同様です (これにより、型チェックの失敗により、「アサーションに失敗しました」という奇妙なエラーが発生します)。- 特定の型の代わりに使用
Any
して、 を返しPartialFunction[Any,Any]
たり、合計関数Function1[Blob,Any]
などを使用したりします。 T
の代わりに型パラメータを使用しBlob
、マクロをパラメータ化して受け入れますPartialFunction[T,Any]
助けていただければ幸いです。私はScala 2.11.8をストレートマクロで使用しています(「マクロパラダイス」はありません)。