【问题标题】:Adding context to rewrite rules添加上下文以重写规则
【发布时间】: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


【解决方案1】:

通常,one can add type signatures to the variables in the forall。类似的东西

{-# RULES "myrule" forall (x :: H a => T a). g (f x) = h x #-}

现在,这在这种情况下完全不起作用,因为T 可能不是单射的。幸运的是,我认为TypeApplications 为我们提供了解决这个问题的方法,它允许我们通知 GHC,x 的类型 T a 中的类型变量 ah 中的变量相同:

{-# LANGUAGE TypeFamilies, TypeApplications, AllowAmbiguousTypes #-}

 ...

{-# RULES "myrule" forall (x :: H a => T a). g (f x) = h @a x #-}

我们不需要启用ScopedTypeVariables(即使我们依赖它来确保as 相同),因为它在重写规则中默认处于启用状态。

【讨论】:

  • @Clinton 请做!我不完全确定 AllowAmbiguousTypes 不只是推迟一个类型错误(在它尝试内联之前不会表现出来)。
  • 我试试看,谢谢你的回答! (抱歉之前删除了评论而不是编辑)
猜你喜欢
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-10
  • 2016-03-13
  • 2016-02-28
相关资源
最近更新 更多