5

'`#に対して'` *種類と一致しませんでした:は一体ここで何が起こっているか

"Couldn't match kind `*' against `#'" 

私はTemplateHaskell(ghci -XTemplateHaskell)を使用して、GHCiの中で次のことをしようとしていた

$(reify ''Show >>= dataToExpQ (const Nothing)) 

を私はこれからExpを得ることを望んでいました(これはShowのインスタンスを持っています)。私は、実際のデータとして文字列としてではなく利用できるように、アプリケーション内にhaskell型に関する情報を挿入するためにこれを行っています。

が私の目標は以下の通りです:

info :: Info 
info = $(reify ''Show >>= dataToExpQ (const Nothing)) 

私は本当にとにかく「#」が何であるか、そのエラーメッセージを理解していませんか? #がある場合は、# -> #または* -> #ですか?それは型のような種類に関係するものですか(私はそれが何であるかも知りませんが)?


さて、GHCには種類の階層があり、 `# 'は特別な種類のボックス化されていない種類です。すべてうまくいっていますが、なぜこのエラーはポップアップしますか?たぶんunboxed型はgenercisでうまくいっていないのでしょうか?

私は、ボックス化されていない型はコンパイラによって最適化されていると考えているので、これは私にとってまだ意味があるとは思えません。また、データのインスタンスが存在する場合、データ構造に含めることができるすべての型に対して、そのインスタンスが存在する必要があるとも考えました。

さらに調査すると、Namesが問題を提起すると思いますが、dataToExpQでそれらを回避する方法はありますか?とにかくその議論をどのように使うか?

+5

'#'は非ボックス型の種類です。http://stackoverflow.com/a/3034295/700253を参照してください。 – Vitus

+0

ヒントのおかげで。そう:どのように問題を解決する:-)? – scravy

答えて

4

これは問題の原因となる名前です。より具体的には、問題は、NameFlavourデータ型のフィールドの一部にボックス化されていない整数があることです。

Data NameFlavorインスタンスには、いくつかの赤いフラグが立てられます。ソースをクリックすると、gfoldlの定義は本質的に整数のようなボックス化されていない整数を扱うことがわかります。これは、実際にはNameUが(Int :: *)にNameUを適用するExp用語を作成します。これは、DataToExpQが偽のData NameFlavourインスタンスによって騙されたために表示されるエラーの原因になります。 (アンボックス化された)(Int#::#)。

したがって、NameFlavourのDataインスタンスは、dataToExpQで仮定された不変量に反するという問題があります。しかし、心配しないで!このシナリオは、dataToExpQが引数を取る理由のために正当な理由があります。引数を指定すると、面倒な型の特別な処理が可能になります。以下では、ボックス化されていない整数フィールドを持つNameFlavourコンストラクタを正しく反映するためにこれを行います。

そこには解決策があるかもしれませんが、私はそれらを認識していないので、次のように転記しました。 THステージングの制限のため、別のモジュールが必要です。

{-# LANGUAGE TemplateHaskell #-} 
{-# LANGUAGE MagicHash #-} 

module Stage0 where 

import Language.Haskell.TH 
import Language.Haskell.TH.Syntax 

import GHC.Types (Int(I#)) 
import GHC.Prim (Int#) 

unboxed :: Int# -> Q Exp 
unboxed i = litE $ intPrimL $ toInteger $ I# i -- TH does support unboxed literals 

nameFlavorToQExp :: NameFlavour -> Maybe (Q Exp) 
nameFlavorToQExp n = case n of 
    NameU i -> Just [| NameU $(unboxed i) |] 
    NameL i -> Just [| NameL $(unboxed i) |] 
    _ -> Nothing 

次に、私のためにコンパイルします。私たちはここのために後方に曲げている箱なし整数はGHCが内部で使用する「ユニーク」に対応し

{-# LANGUAGE TemplateHaskell #-} 

import Language.Haskell.TH 
import Language.Haskell.TH.Quote 

import Generics.SYB 
import Stage0 

info :: Info 
info = $(reify ''Show >>= dataToExpQ (mkQ Nothing nameFlavorToQExp)) 

CAVEATプログラマ。必ずしもシリアル化されるとは限りません。結果のInfo値をどのように使用しているかによって、これは爆発を引き起こす可能性があります。

また、ショーを表示するときに、スコープ内にあるショーのすべてのインスタンスも表示しています。

  • 非常に多くの構文があります。

  • the documentationには、これらのインスタンスにはメソッド定義が含まれていません。

HTH。

関連する問題