如何允许统一具有不同类型的类型变量?

时间:2012-11-27 18:55:40

标签: haskell types repa

我有一个带有以下类型签名的函数

{-# LANGUAGE FlexibleContexts #-}
dataLat :: Load r DIM1 Double
        => (Array r DIM1 Double -> Array U DIM1 Double, Array U DIM1 Double)

ArrayUDIM1来自Repa库。 dataLat创建稍后作为元组传递给其他函数的数据。有一点r类型变量与D类型统一(这又来自Repa),但稍后r也应该与类型L统一(这是我的类型)。问题是它已与D统一,因此无法与L统一。我最终遇到Couldn't match expected type错误。我认为这应该通过某种形式的更高等级类型来解决,但我无法弄清楚应该如何编写。任何人都可以帮我一把吗?

2 个答案:

答案 0 :(得分:3)

Try {-# LANGUAGE NoMonomorphismRestriction #-}

http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/monomorphism.html

答案 1 :(得分:2)

您可以使用dataLatRank2Types提供一个类型,说明它返回多态函数。

newtype Unboxer =
  Unboxer {applyUnboxer :: forall repr. Load repr DIM1 Double => Array repr DIM1 Double -> Array U DIM1 Double}

dataLat :: (Unboxer, Array U DIM1 Double)

dataLat的正文必须将多态函数放入Unboxer。字段访问器applyUnboxer返回可以在不同类型中使用的多态函数。

我不清楚你真的需要等级2类型。由于dataLat不带参数,因此您可以将unboxer定义为具有普通rank-1多态性的全局函数。

准确地说,将类型变量统一为多个类型是没有意义的。将rUD统一起来相当于说r == UU == D,这是假的。上面的代码允许函数实例化到多种类型。将实例化视为在分配类型之前复制代码,因此您有一个函数实例r₁ == U和一个单独的实例r₂ == D