gpt4 book ai didi

arrays - ST monad 中使用数组卡住导致的类型变量不明确

转载 作者:行者123 更新时间:2023-12-02 18:20:35 27 4
gpt4 key购买 nike

以下代码创建数组,初始化,然后返回不可变数组。

import Data.Array
import Control.Monad.ST
import Data.Array.ST
import qualified Data.Array.IArray as IA

createCustomeInitializedArray = do
arr <- newArray (0,10) 0 :: ST s (STArray s Int Int)
-- some mutation writeArray arr 0 1 etc
iarr <- freeze arr -- :: ST s (IA.IArray Array s)
return iarr

iarr <- freeze arr导致类型错误

> No instance for (IA.IArray b0 Int) arising from a use of `freeze'
> The type variable `b0' is ambiguous

我尝试过注释掉类型签名和其他变体,但到目前为止还没有运气。请在答案中包含涉及如何解决该问题的思考过程。

最佳答案

您的函数具有以下最通用的类​​型:

createCustomeInitializedArray :: IA.IArray a Int => ST s (a Int Int)

其中有一个类型类约束IA.IArray a Int。实际上这有点棘手,因为它将第二个参数中的部分类型类应用于固定类型。 Haskell98 不允许这样做;如果您启用 -XFlexibleContexts 扩展,GHC 就会执行此操作。除此之外,这显然是一个多态类型,但由于 createCustomeInitializedArray 没有(显式)参数,编译器希望将其设为 constant applicative form ,通过dreaded monomorphism restriction 。 IE。它拒绝推断多态类型,您需要使用显式签名来请求它。无论如何,使用顶级签名是一个非常好的主意,所以这样做:

{-# LANGUAGE FlexibleContexts #-}
createCustomeInitializedArray :: IA.IArray a Int => ST s (a Int Int)
createCustomeInitializedArray = do
arr <- newArray (0,10) 0 :: ST s (STArray s Int Int)
-- ...
iarr <- freeze arr
return iarr

我要补充一点,newArray (0,10) 0 的本地签名并不像它看起来的那样:Haskell 类型变量没有作用域,因此 s 对来自边远国家的s一无所知;以下内容更忠实于编译器所看到的内容:

createCustomeInitializedArray :: IA.IArray a Int => ST s (a Int Int)
createCustomeInitializedArray = do
arr <- newArray (0,10) 0 :: ST s₁ (STArray s₁ Int Int)
-- ...

因此,它使本地操作完全多态,独立于外部的 s,然后将其实例化为该状态参数。好吧,在这个特定的示例中,这实际上没有问题,但通常它可能是一个令人讨厌的问题(特别是,对外部 s 的约束不会传播到内部)。因此,这是我推荐的代码:

{-# LANGUAGE FlexibleContexts, ScopedTypeVariables, UnicodeSyntax #-}

createCustomeInitializedArray :: ∀ s a . IA.IArray a Int => ST s (a Int Int)
createCustomeInitializedArray = do
arr <- newArray (0,10) 0 :: ST s (STArray s Int Int)
-- ...
iarr <- freeze arr
return iarr

这也可以更简洁地写为

  arr :: STArray s Int Int <- newArray (0,10) 0

关于arrays - ST monad 中使用数组卡住导致的类型变量不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40007277/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com