Haskell 从数组转换为未装箱数组违反了重写规则

发布于 2025-01-04 12:03:55 字数 1882 浏览 1 评论 0原文

我正在尝试将我的程序从使用 Data.Array 转换为 Data.Array.Unboxed。

作为一个快速旁注: 有几个地方声明我可以在代码中将“Array”更改为“UArray” 并添加 Data.Array.Unboxed 的导入,但是我没有混合两者 数组类型所以 我刚刚导入了 Data.Array.Unboxed 而不是 Data.Array,这是否足够?

当我进行切换时,以下重写规则会中断:

{-# RULES
    "applyWindow/applyWindow" forall win1 win2 image. 
                                     applyWindow win1 
                                                 (applyWindow win2 
                                                 image) = 
                                     applyWindow (indexMult win1 win2) 
                                                            image
  #-}

这里 win1 win2 和图像都应该是 UArray。但是,这无法编译并出现以下错误。

FIPlib/Core.hs:229:99:
    Ambiguous type variables `e0', `a0' in the constraint:
      (IArray a0 e0) arising from a use of `applyWindow'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: applyWindow (indexMult win1 win2) image
    When checking the transformation rule "applyWindow/applyWindow"

FIPlib/Core.hs:229:99:
    Ambiguous type variables `e0', `a2' in the constraint:
      (IArray a2 e0) arising from a use of `applyWindow'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: applyWindow (indexMult win1 win2) image
    When checking the transformation rule "applyWindow/applyWindow"

FIPlib/Core.hs:229:112:
     Ambiguous type variables `e0', `a1' in the constraint:
      (IArray a1 e0) arising from a use of `indexMult'
    Probable fix: add a type signature that fixes these type variable(s)
    In the first argument of `applyWindow', namely
      `(indexMult win1 win2)'
    In the expression: applyWindow (indexMult win1 win2) image
    When checking the transformation rule "applyWindow/applyWindow"

是什么让这变得模棱两可?为什么当它与 Data.Array 一起使用时会中断?

I am trying to convert my program from using Data.Array to Data.Array.Unboxed.

As a quick side note:
several places state that I can change "Array" to "UArray" in my code
and ADD an import of Data.Array.Unboxed, however I am not mixing both
types of arrays so
I just imported Data.Array.Unboxed instead of Data.Array, is this sufficient?

When I make the switch the following rewrite rule breaks:

{-# RULES
    "applyWindow/applyWindow" forall win1 win2 image. 
                                     applyWindow win1 
                                                 (applyWindow win2 
                                                 image) = 
                                     applyWindow (indexMult win1 win2) 
                                                            image
  #-}

Here win1 win2 and image should all be UArrays. However, this fails to compile with the follwing errors.

FIPlib/Core.hs:229:99:
    Ambiguous type variables `e0', `a0' in the constraint:
      (IArray a0 e0) arising from a use of `applyWindow'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: applyWindow (indexMult win1 win2) image
    When checking the transformation rule "applyWindow/applyWindow"

FIPlib/Core.hs:229:99:
    Ambiguous type variables `e0', `a2' in the constraint:
      (IArray a2 e0) arising from a use of `applyWindow'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: applyWindow (indexMult win1 win2) image
    When checking the transformation rule "applyWindow/applyWindow"

FIPlib/Core.hs:229:112:
     Ambiguous type variables `e0', `a1' in the constraint:
      (IArray a1 e0) arising from a use of `indexMult'
    Probable fix: add a type signature that fixes these type variable(s)
    In the first argument of `applyWindow', namely
      `(indexMult win1 win2)'
    In the expression: applyWindow (indexMult win1 win2) image
    When checking the transformation rule "applyWindow/applyWindow"

What makes this ambiguous? Why does this break when it works with Data.Array?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鲜血染红嫁衣 2025-01-11 12:03:55

问题在于 Data.Array.Unboxed 重新导出 Data.Array.IArray,从而导出不可变数组接口的 IArray 类,但是Data.Array 没有(它甚至没有导入它)。因此,如果您使用诸如 boundsaccumArrayarray 等仅导入 Data.Array 的函数,则它们是数组类型中的单态性,因此不会出现歧义(元素类型中的多态性显然不会在这里造成问题,它会在适当的类型类约束下产生问题)。但如果导入 Data.Array.Unboxed,所有这些函数都会获得 IArray a e 约束,因此重写可能会涉及不同的数组类型,从而导致中断。您需要在函数或 int 规则上使用类型签名来修复类型。如果没有看到代码,我无法确切地说如何解决这个问题。

注意:类型检查在 7.4 中发生了变化,在 ghc-7.4.1 中,如果导入 Data.Array.Unboxed,没有规则的代码在没有类型签名的情况下无法编译。

要修复类型,以便规则不会出现歧义,您必须

  • 在顶层为 applyWindow
  • paggedImage和<代码>filteredPlatedImage。

可能期望且最合理的是所有涉及的数组具有相同的类型,可以是

  1. 单态类型,例如 UArray (Int,Int) Int(元素类型也可以是 Word< /code>, ...)
  2. 数组类型中的单态类型和元素类型中的多态类型
  3. 两者中的多态类型

对于 1.,您只需添加签名, applyWindow :: T -> T-> TxxImage :: T (其中 T 是所需的类型)。对于2.,您必须添加两个语言扩展,FlexibleContextsScopedTypeVariables,然后applyWindow将获得签名

applyWindow :: forall e. (Num e, IArray UArray e)
            => UArray (Int,Int) e -> UArray (Int,Int) e -> UArray (Int,Int) e

,本地绑定将获得签名xxImage :: UArray (Int,Int) e。需要 FlexibleContexts 来允许 constarint 中出现 UArray,并且需要 ScopedTypeVariables 来将元素类型引入作用域,以便 paddedImagefilteredPlatedImage 完全可以获取类型签名。对于 3.,只需要 ScopedTypeVariablesapplyWindow 的类型签名将是

applyWindow :: forall a e. (Num e, IArray a e) => ...

另一种强制所有数组为同一类型的方法是使用 asTypeOf 或将它们全部放入列表中(未使用的本地绑定),但 IMO 类型签名更可取。

一旦所有类型都被固定(它们不一定相同,但本地绑定的类型必须由参数和结果类型确定,可能仅由参数类型确定),规则应该进行类型检查。 (可能还需要修复 indexMult 中的类型。)

The problem is that Data.Array.Unboxed reexports Data.Array.IArray, and hence the IArray class for the immutable-array interface, but Data.Array doesn't (it doesn't even import it). So if you use functions like bounds, accumArray, array etc. with only Data.Array imported, they are monomorphic in the array type, thus no ambiguity arises (the polymorphism in the element type apparently doesn't pose a problem here, it would with suitable type class constraints). But if you import Data.Array.Unboxed, all these functions get an IArray a e constraint, and thus the rewriting might involve different array types, thus breaks. You need to fix the types with type signatures, on the functions or int the rule. How exactly to solve this I cannot say without seeing the code.

Note: Type checking has changed with 7.4, with ghc-7.4.1, the code without the rule doesn't compile without type signatures if importing Data.Array.Unboxed.

To fix the types, so that the rule doesn't run into ambiguity, you have to give type signatures

  • on the top-level, to applyWindow,
  • to the two local bindings of paddedImage and filteredPaddedImage.

The probably desired and most reasonable is for all involved arrays to have the same type, that can be

  1. a monmorphic type, say UArray (Int,Int) Int (element type could also be Word, ...)
  2. a type monomorphic in the array type and polymorphic in the element type
  3. a type ploymorphic in both

For 1., you simply have to add the signatures, applyWindow :: T -> T -> T and xxImage :: T (where T is the desired type). For 2., you have to add two language extensions, FlexibleContexts and ScopedTypeVariables, then applyWindow would get the signature

applyWindow :: forall e. (Num e, IArray UArray e)
            => UArray (Int,Int) e -> UArray (Int,Int) e -> UArray (Int,Int) e

and the local bindings would get the signature xxImage :: UArray (Int,Int) e. FlexibleContexts is needed to allow the occurrence of UArray in the constarint, and ScopedTypeVariables is necessary to bring the element type into scope so that paddedImage and filteredPaddedImage can get type signatures at all. For 3., only ScopedTypeVariables is needed, the type signature of applyWindow would then be

applyWindow :: forall a e. (Num e, IArray a e) => ...

Another method to force all arrays to the same type is using asTypeOf or putting them all into a list (unused local binding), but IMO type signatures are preferable.

Once all types are fixed (they need not necessarily be the same, but the type of the local bindings must be determined by the argument and result types, possibly the argument types alone), the rule should type check. (It may be necessary to fix types in indexMult too.)

噩梦成真你也成魔 2025-01-11 12:03:55

I've received exactly same error message (about IArray etc.) when I tried running this code without the explicit type signature for the array (UArray Int Bool in that case), just with the Data.Array.Unboxed import. When I added the signature all was OK. Maybe this will help you too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文