【发布时间】:2017-02-17 09:40:15
【问题描述】:
在下面的代码中,我想尽可能将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
#-}
这是错误:
• 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"
注意可能的修复方法:add (H a) to the context of the RULE "myrule"。这似乎可以完成这项工作,但我不确定如何实际做到这一点。 a 甚至没有在规则中提及,所以我不确定当 a 不涉及任何内容时添加 H a 会有什么帮助。
如果有什么不同,我控制的唯一代码是类H。我无法更改G。我的代码当然比这更复杂,但是如果我能看到一个如何让这个简化的例子工作的例子,我应该能够计算出我认为的代码。
尝试失败:
我在下面尝试了@Alec 的建议,但它似乎不起作用,重写规则没有被触发。这是我尝试过的代码:
{-# 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 不起作用,它会导致下游编译时错误。为了使这种行为表现出来,首先需要触发规则。触发规则听起来像是一个单独的问题。再次,对我的评论持保留态度 - 我很可能完全错了。
标签: haskell optimization ghc