次のコードでは、可能であればg . f
をh
と書き換えたいと思います。 h
がクラスのインスタンスを持っていない場合があるかもしれませんが、可能であれば書き直したいと思います。これが達成可能であることを示すエラーメッセージが表示されますが、変更する必要があるかどうかはわかりません。書き換えルールにコンテキストを追加する
{-# LANGUAGE TypeFamilies #-}
main = return()
data D a
f :: a -> D a
f = undefined
type family T a
class G a where
g :: D (T a) -> a
class H a where
h :: T a -> a
{-# RULES
"myrule" forall x. g (f x) = h x
#-}
アンこれは誤りである:ここで
は、いくつかのサンプルコードですadd (H a) to the context of the RULE "myrule"
:
• Could not deduce (H a) arising from a use of ‘h’
from the context: G a
bound by the RULE "myrule" at trickyrewrite.hs:19:3-34
Possible fix: add (H a) to the context of the RULE "myrule"
• In the expression: h x
When checking the transformation rule "myrule"
可能性の修正に注意してください。これは仕事をするようですが、私は実際にこれを行う方法がわかりません。 a
はルールにも言及されていないので、が何も参照していないときにH a
を追加するとどのように役立つのか分かりません。
違いがある場合は、私が制御するコードはクラスH
です。私はG
を変更できません。もちろん、私のコードはこれよりも複雑ですが、この単純化されたサンプルをどのように動作させるかという実例を見ることができれば、自分のコードを理解することができます。
未遂:
書き換えルールがトリガされていない、私は以下のアレックの提案@試みたが、動作するようには思えません。私が試したコードは次のとおりです。
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
module Main where
main = ((g (f (2 :: Int))) :: Char) `seq` return()
data D a
{-# INLINE [1] f #-}
f :: a -> D a
f = undefined
type family T a
type instance T Char = Int
{-# INLINE [1] g' #-}
g' :: (G a) => D (T a) -> a
g' = undefined
class G a where
g :: D (T a) -> a
g = g'
instance G Char
class H a where
h :: T a -> a
{-# RULES
"myrule" forall (x :: H a => T a). g' (f x) = h @a x
#-}
FWIW私の解決策はまだわかっていません。通常、AllowAmbiguousTypesが機能しない場合は、コンパイル時にエラーが発生します。その動作が明示されるには、最初にルールをトリガする必要があります。ルールのトリガーは別の問題のように聞こえる。再び、塩の穀粒で私のコメントを取る - 私は非常によく完全に間違っている可能性があります。 – Alec