gpt4 book ai didi

haskell - MonadRef 纯实现

转载 作者:行者123 更新时间:2023-12-02 04:07:32 30 4
gpt4 key购买 nike

我正在研究this problemMonadRef 相关。当看定义时

class MonadRef r m | m -> r where
newRef :: a -> m (r a)
readRef :: r a -> m a
writeRef :: r a -> a -> m ()

我在想如何用纯数据结构来实现这个,但未能找到答案。实际上,所有已知的独立实现(不依赖于另一个 MonadRef)

instance TVar STM
instance IORef IO
instance (STRef s) (ST s)

要求实践中的RealWorld。这是否意味着我们只能拥有不纯的 MonadRef

当我尝试解决这个问题时,我首先发现 Maybe 无法实现 MonadRef 只是因为它太简单了,没有空间来记录所需的内容信息。作为这一点的概括,我得出的结论是,对于任何实现,Monad 都必须能够包含任意数量的信息,因为您可以多次调用 newRef

所以我考虑了[],但它仍然失败,因为 Monad 中存储的数据可以是任何类型。我不知道如何在 Haskell 中构建一个可以存储任何类型数据的容器,同时仍然能够以正确的类型提取数据(也许 existential quantification 可以提供帮助?但我仍然不知道该怎么做所以)。

最佳答案

通过使用状态为 State 的 monad,您几乎可以实现这一点(纯粹实现与 ST 等效的功能) >将字典从引用ID映射到该引用内的值。

但是 Haskell 的类型系统缺乏依赖类型,其中值的类型依赖于另一个固定类型项的。因此,它不能表示引用内的类型取决于引用的 ID,从而允许所有类型。

您可以通过让存储的值的类型为 GHC.Exts.Any 并使用来解决此问题Unsafe.Coerce.unsafeCoerce 在内部转换为正确的类型。

但是,正如宣传的那样,unsafeCoerce 是不安全的。这再次意味着 Haskell 的类型系统无法向您保证您正在以类型安全的方式使用引用,并且如果您犯了错误,您可能会导致 GHC 以这种方式崩溃。 (如果 MonadRef 在其引用内容上有一个 Data.Typeable.Typeable 约束,则可以用来执行此操作,但事实并非如此。(而且您可以然后将 Data.Dynamic.Dynamic 而不是 Any 放入 map 内。))

但是,如果您确实以这种方式使用unsafeCoerce,请注意隐藏所使用的 ID 类型,并实现与 ST< 相同的 API/code> 确实如此,包括防止不同 ST“线程”混淆彼此引用的 s 参数,那么这实际上应该作为一个库安全地工作。我发现at least one attempt on GitHub 。 (它也尝试充当变压器,尽管我怀疑这是否安全。)

关于haskell - MonadRef 纯实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24366607/

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