【问题标题】:How to allow unification of a type variable with different types?如何允许统一具有不同类型的类型变量?
【发布时间】:2012-11-27 18:55:39
【问题描述】:

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

{-# 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 错误。我认为这应该通过某种形式的更高级别的类型来解决,但我无法弄清楚应该如何写。谁能帮帮我?

【问题讨论】:

    标签: haskell types repa


    【解决方案1】:
    Try {-# LANGUAGE NoMonomorphismRestriction #-}
    

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

    【讨论】:

    • 宾果游戏!我突然想到这可能是由单态性引起的——我不知道我为什么不检查它。
    【解决方案2】:

    你可以给dataLat一个类型,说它返回一个多态函数,使用Rank2Types

    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 不带参数,因此您可以将拆箱器定义为具有普通 rank-1 多态性的全局函数。

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

    【讨论】:

    • 感谢散热器,但这种解决方法将迫使我在许多地方更改我的代码。 Ben 的答案是正确的 - 问题是由单态限制引起的。
    猜你喜欢
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    • 2018-10-13
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多