Haskell 对于引用是否有一个typeclass类似于可变数组的MArray类?
MArray类提供了在ST和IO上下文中使用各种可变数组的通用函数。我还没有找到一个可以同时使用STRefs和IORefs的类似类。这样的东西存在吗?软件包提供:Haskell 对于引用是否有一个typeclass类似于可变数组的MArray类?,haskell,typeclass,mutable,Haskell,Typeclass,Mutable,MArray类提供了在ST和IO上下文中使用各种可变数组的通用函数。我还没有找到一个可以同时使用STRefs和IORefs的类似类。这样的东西存在吗?软件包提供: class Monad m => MonadRef r m | m -> r where [...] 或对于类型族: 另一个答案建议使用不具有函数依赖性的包。它还具有独立的HasGet和HasPut成员,对newRef功能没有抽象 除了每种方法中的不同方法外,功能依赖性是一种设计权衡。考虑下面两个简化类: cla
class Monad m => MonadRef r m | m -> r where
[...]
或对于类型族:
另一个答案建议使用不具有函数依赖性的包。它还具有独立的HasGet
和HasPut
成员,对newRef
功能没有抽象
除了每种方法中的不同方法外,功能依赖性是一种设计权衡。考虑下面两个简化类:
class MRef1 r m where
newRef1 :: a -> m (r a)
readRef1 :: r a -> m a
class MRef2 r m | m -> r where
newRef2 :: a -> m (r a)
readRef2 :: r a -> m a
使用MRef1
,monad类型和reference类型都可以自由变化,因此以下代码存在类型错误:
useMRef1 :: ST s Int
useMRef1 = do
r <- newRef1 5
readRef1 r
No instance for (MRef1 r0 (ST s)) arising from a use of `newRef1'
The type variable `r0' is ambiguous
MRef1
实例很好,因为同一monad类型允许使用多个引用类型:
instance MRef1 (STRefHistory s) (ST s) where
newRef1 a = STRefHistory <$> newSTRef [a]
readRef1 (STRefHistory r) = head <$> readSTRef r
我还提到了类型族版本,它在表达能力上与函数依赖性非常相似;引用类型是monad类型的“类型函数”,因此每个monad只能有一个。语法有点不同,特别是您可以在约束中说MonadRef m
,而不说明约束中的引用类型
相反的功能依赖性也是合理的:
class MRef2 r m | r -> m where
因此,每个引用类型只能存在于一个monad中,但对于一个monad,仍然可以有多个引用类型。然后,你需要在引用上使用类型签名,而不是在整个一元计算上。有一个typeclass,它允许你
获取和放置IOREF和STREF相同。我认为这些“引用”是不同的,因为它们有不同的含义。也就是说,IORef
无法与STRef
相比进行优化。而TVar
是一种乐观的并行计算元素。ref-fd与monad-statevar相比如何?据我所知,IORef
和STRef
都有相同的底层实现。只是您可以使用runST
对ST
monad进行“转义”monad statevar
不具有从monad类型到引用类型的函数依赖性,这意味着它可以容纳更多实例(例如,您可能会找到其他引用类型用于IO)但是使用ref-fd
进行类型推断通常会更好。我编辑了这篇文章,添加了一些关于选项的讨论。monad statevar与ref-fd相比如何?
instance MRef1 (STRefHistory s) (ST s) where
newRef1 a = STRefHistory <$> newSTRef [a]
readRef1 (STRefHistory r) = head <$> readSTRef r
Functional dependencies conflict between instance declarations:
instance MRef2 (STRef s) (ST s) -- Defined at mref.hs:28:10
instance MRef2 (STRefHistory s) (ST s) -- Defined at mref.hs:43:10
class MRef2 r m | r -> m where