1

我正在尝试将我的程序从使用 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 和 image 应该都是 UArrays。但是,这无法编译并出现以下错误。

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 一起使用时会中断?

4

2 回答 2

3

问题是Data.Array.Unboxedreexports Data.Array.IArray,因此是IArrayimmutable-array 接口的类,但Data.Array没有(它甚至不导入它)。因此,如果您使用仅导入的,等函数bounds,它们在数组类型中是单态的,因此不会出现歧义(元素类型中的多态性在这里显然不会造成问题,它会使用合适的类型类约束) . 但是如果你 import ,所有这些函数都会受到约束,因此重写可能涉及不同的数组类型,从而中断。您需要使用类型签名、函数或 int 规则来修复类型。如果没有看到代码,我不能说到底如何解决这个问题。accumArrayarrayData.ArrayData.Array.UnboxedIArray a e

注意:类型检查在 7.4 中发生了变化,在 ghc-7.4.1 中,如果导入Data.Array.Unboxed.

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

  • 在顶层,到applyWindow,
  • paddedImage到和的两个本地绑定filteredPaddedImage

可能需要和最合理的是所有涉及的数组都具有相同的类型,可以是

  1. 一个单态类型,比如说UArray (Int,Int) Int(元素类型也可以是Word,...)
  2. 数组类型中的单态类型和元素类型中的多态类型
  3. 两者中的多态类型

对于 1.,您只需添加签名applyWindow :: T -> T -> TxxImage :: TT所需类型在哪里)。对于 2.,您必须添加两个语言扩展名,然后FlexibleContexts将获得签名ScopedTypeVariablesapplyWindow

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

并且本地绑定将获得签名xxImage :: UArray (Int,Int) eFlexibleContexts需要允许UArray在约束中出现,并且ScopedTypeVariables需要将元素类型带入范围以便paddedImage并且filteredPaddedImage可以完全获得类型签名。对于 3., onlyScopedTypeVariables是必需的,applyWindow然后的类型签名将是

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

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

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

于 2012-02-12T17:42:52.427 回答
2

当我尝试在没有数组的显式类型签名(在这种情况下)的情况下运行此代码时,我收到了完全相同的错误消息(关于 IArray 等)UArray Int Bool,仅使用Data.Array.Unboxed导入。当我添加签名时,一切正常。也许这对你也有帮助。

于 2012-02-12T01:22:37.410 回答