Arrays 数据结构中是否有ST(U)阵列?

Arrays 数据结构中是否有ST(U)阵列?,arrays,haskell,typeclass,starray,Arrays,Haskell,Typeclass,Starray,我必须做什么才能使GHC接受此代码: {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} module STTest where import Data.Array.ST import Control.Monad.ST.Strict as S import Control.Monad.ST.Lazy as L -- ST monad arrays (unboxed in actual code) type Arr s a =

我必须做什么才能使GHC接受此代码:

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}

module STTest where

import Data.Array.ST
import Control.Monad.ST.Strict as S
import Control.Monad.ST.Lazy as L

-- ST monad arrays (unboxed in actual code)
type Arr s a = STArray s Int a

-- representing some algorithm that works on these STArrays
data ArrGen s a = ArrGen (a -> S.ST s (Arr s a)) (Arr s a -> S.ST s ())

-- class for some "generator"
class Generator g a where
  gen :: g -> a -> [a]

instance Generator (ArrGen s a) a where
  gen (ArrGen create apply) s = L.runST $ do
    a <- strictToLazyST $ create s -- DOES NOT WORK
    strictToLazyST $ apply a >> getElems a
但是,这样做很好:

data Dummy
create' :: a -> S.ST s (Arr s a)
create' = undefined
apply' :: Arr s a -> S.ST s [a]
apply' = undefined

instance Generator Dummy a where
  gen _ s = L.runST $ do
    a <- strictToLazyST $ create' s
    strictToLazyST $ apply' a >> getElems a
那么这就失败了:

instance (HasSTU a) => Generator (ArrayGen a) a [a] where
  gens (AG c u p) s = fmap (fmap p) $ L.runST $ do
    ar <- strictToLazyST $ (c s)
    streamM $ strictToLazyST $ u ar >> getElems ar -- can't use getElems here!

streamM :: (Applicative f) => f a -> f (Stream a))
streamM = Cons <$> a <*> streamM a
尽管上下文(HasSTU a)说(在我的脑海中)所有的s都有一个(MArray(stus)a(s.ST s))上下文,但它似乎不这么认为。我试图通过更改(AU a)类型来修复它:

它看起来像是打字检查,但我无法实际使用它。同样,如果我改为:

class (Integral a, Bits a, forall s. MArray (STUArray s) a (S.ST s)) => HasSTU s a
type AC a = (forall s. HasSTU s a) => a -> S.ST s (STUArray s Int a)
...
instance (forall s. HasSTU s a) => Generator (ArrayGen a) a [a] where
  ...

instance forall s. HasSTU s Word32 -- !!!
但当我尝试运行某个程序时:

Could not deduce (forall s. HasSTU s Word32)

我讨厌这件事!为什么?我有一个例子,所有的s!我真的不知道我应该把孔放在哪里以及到底发生了什么。

问题是
runST
需要
孔。ST s t
参数,但您的类型修复了
s
,因此在一元操作中使用
create
apply
使其不适合
runST

在我看来,您的用例并不禁止提供
ArrGen
多态(在
s
中)参数,所以

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, RankNTypes #-}

module STTest where

import Data.Array.ST
import Control.Monad.ST.Strict as S
import Control.Monad.ST.Lazy as L

-- ST monad arrays (unboxed in actual code)
type Arr s a = STArray s Int a

-- representing some algorithm that works on these STArrays
data ArrGen a = ArrGen (forall s. a -> S.ST s (Arr s a)) (forall s. Arr s a -> S.ST s ())

-- class for some "generator"
class Generator g a where
  gen :: g -> a -> [a]

instance Generator (ArrGen a) a where
  gen (ArrGen create apply) s = L.runST $ do
    a <- strictToLazyST $ create s -- DOES NOT WORK
    strictToLazyST $ apply a >> getElems a
{-#语言多段类型类、FlexibleInstances、RankNTypes}
模块测试在哪里
导入Data.Array.ST
进口管制。Monad.ST.严格按照S
导入控制.Monad.ST.Lazy作为L
--ST monad数组(在实际代码中取消装箱)
类型Arr s a=星型s Int a
--表示在这些星空上工作的一些算法
数据ArrGen a=ArrGen(适用于所有s.a->s.ST s(Arr s a))(适用于所有s.Arr s a->s.ST s())
--某些“生成器”的类
类别生成器g a在哪里
gen::g->a->[a]
实例生成器(ArrGen a)a其中
gen(ArrGen创建应用)s=L.runST$do
a>getElems a
使组件具有多态性(至少在编译的意义上,您的用例可能禁止这种方法)

为什么它只适用于第二个而不适用于第一个


因为在那里,
s
不是固定的,计算在
s
中是完全多态的,正如
runST
所要求的那样,谢谢你的回答!这让我更进一步。。。但我仍然无法使用STUArray。这太令人沮丧了!我几乎要放弃了,一直使用IArray,因为这个圣莫纳德让我觉得完全迷失了方向。我已经更新了我的问题,有什么想法吗?编译器不是已经在
类(积分a,位a,forall s.MArray(stus数组)a(s.ST s))=>HasSTU a
上完全呕吐了吗?如果没有,从什么时候开始允许对所有ed上下文执行
ed操作?不管怎么说,现在还不知道该怎么做。让它成为非ST的东西,并在每个步骤中使用
runST
unsafeThaw
unsafeFreeze
type AU a = (HasSTU a) => forall s. STUArray s Int a -> S.ST s [a]
class (Integral a, Bits a, forall s. MArray (STUArray s) a (S.ST s)) => HasSTU s a
type AC a = (forall s. HasSTU s a) => a -> S.ST s (STUArray s Int a)
...
instance (forall s. HasSTU s a) => Generator (ArrayGen a) a [a] where
  ...

instance forall s. HasSTU s Word32 -- !!!
Could not deduce (forall s. HasSTU s Word32)
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, RankNTypes #-}

module STTest where

import Data.Array.ST
import Control.Monad.ST.Strict as S
import Control.Monad.ST.Lazy as L

-- ST monad arrays (unboxed in actual code)
type Arr s a = STArray s Int a

-- representing some algorithm that works on these STArrays
data ArrGen a = ArrGen (forall s. a -> S.ST s (Arr s a)) (forall s. Arr s a -> S.ST s ())

-- class for some "generator"
class Generator g a where
  gen :: g -> a -> [a]

instance Generator (ArrGen a) a where
  gen (ArrGen create apply) s = L.runST $ do
    a <- strictToLazyST $ create s -- DOES NOT WORK
    strictToLazyST $ apply a >> getElems a