haskell - 使用向量 `create` 函数组合任何函数时出现类型错误

标签 haskell

下面的代码不会被编译:

import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Unboxed.Mutable as MV

bad :: V.Vector Int
bad = id . V.create $ do
    v <- MV.new 1
    MV.set v 0
    pure v
• Couldn't match type ‘m0 (MV.MVector
                             (Control.Monad.Primitive.PrimState m0) a0)’
                 with ‘forall s. GHC.ST.ST s (MV.MVector s Int)’
  Expected type: m0 (MV.MVector
                       (Control.Monad.Primitive.PrimState m0) a0)
                 -> V.Vector Int
    Actual type: (forall s. GHC.ST.ST s (MV.MVector s Int))
                 -> V.Vector Int
• In the second argument of ‘(.)’, namely ‘V.create’
  In the expression: id . V.create
  In the expression:
    id . V.create
    $ do { v <- MV.new 1;
           MV.set v 0;
           pure v }

但接下来会是:

import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Unboxed.Mutable as MV


good :: V.Vector Int
good = id <b>$</b> V.create $ do
    v <- MV.new 1
    MV.set v 0
    pure v

stack 解析器是 lts-9.12

那么,如果我更喜欢按 (.) 组合,为什么会这样以及如何解决?

最佳答案

您已经明白了 GHC 无法执行谓词多态性这一事实。 V.create 具有更高等级的类型 forall a。拆箱 a => (forall s. ST s (MVector s a)) -> Vector a,当你尝试将它应用到 (id .)::(x -> y) -> ( x -> y) 你最终需要实例化 x = forall s。 ST s (MVector s a),它爆炸了。这并不是说所需的实例化真的有什么错误;只是 GHC 无法处理它。曾经有一个扩展,ImpredicativePolymorphism,它试图提供有限的支持,但从 GHC 8 开始,它已被完全破坏和弃用。 ($) 仍然有效的原因是因为它实际上是硬连接到 GHC 中的,这样它就可以避免这个问题,这就是为什么如果你试图定义

f $$ x = f x

并在这里使用它而不是 ($) 它会像 (id .) 一样失败。

关于haskell - 使用向量 `create` 函数组合任何函数时出现类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47239014/

相关文章:

Haskell:如何使用这个数据结构

haskell - 是否有 “dual”用于缩放?

haskell - 在 Haskell 中实例化列表的最短方法是什么?

haskell - 内部模块的跨模块内联

haskell - 如何在 haskell 中使用合理的缩进初始化矩阵

haskell - 在haskell中处理事件流

haskell - 是否可以让 Leksah 为其工作区使用 cabal-dev 环境?

haskell - 'fmapDefault' 中的 'Data.Traversable' 有什么意义?

haskell - 复杂状态 Monad 结构

loops - Haskell - for 循环