Context:在考虑典型的命令式语言中的函数签名时,有些参数可能被表示为可变引用,有些参数可能被表示为不可变引用,有些参数可能被看作是简单的纯常数。
我试图了解如何在Haskell中重现这种情况,最重要的是对依赖于状态的变量的mutableimmutable处理。
在Haskell中,有几种管理状态的方法,其中一种方法似乎是通过 State
StateT
MonadState
其中很适合单体变换器。在有状态的函数参数中,如果我想明确在函数体内部应该被认为是不可变的,我相信这个问题的答案。在哈斯克尔中为一个状态制作只读函数。 很好地解释了如何做到这一点,通过使用 Reader
或 MonadReader
.
另一种管理状态的方法(我对这种情况比较感兴趣),是用 ST
. 我喜欢 ST
更好,因为它允许同时管理多个内存单元,而且它的性能似乎比 State
.现在的问题是,我不知道如何正确管理在 ST
. 该 Reader
方式似乎不适用这种情况。我一直在看 STMonadTrans
包,这似乎有助于使 ST
与单体变压器相适应,但我不知道如何使用它。
问题:请问你有一个简单的函数例子吗?你有一个简单的函数例子吗?f
创建了一个可变的 x
与 newSTRef
,并通过 x
到函数 g
以一种不可改变的方式,也就是说,以这样一种方式,即 g
会看 x
而不是修改 x
? 如果没有,有什么变通的办法吗?
注1: 一个变通的方法是在传递变量之前冻结变量,使之成为纯变量,但是在我的例子中,这不是一个可以接受的解决方案,因为冻结要么是昂贵的,要么是不安全的,而且不可能快速冻结复杂的结构,比如向量的向量。不安全的胁迫也是不可接受的。我正在寻找一个安全的零运行时成本的解决方案。
备注2:有人说我可以先读引用再进入函数,但这是对我简化问题的过度简化回答。在更普遍的情况下,有可能不能做到以下几点 readSTRef
可变 x
在进入功能前 g
因为 x
是比较复杂的,像一组可变数组.我还是用这种简单的方式来问我的问题,试图弄清楚如何在一个简单的例子上做一般的事情。
谢谢你
我没有读过评论区的小说,但像这样的模式
newtype ReadOnly s a = ReadOnly (ST s a)
makeReadOnly :: STRef s a -> ReadOnly s a
makeReadOnly = ReadOnly . readSTRef
已经对我起到了很好的作用。 这是一个经典的技巧:如果你想让一个数据类型支持某些操作,只需将数据类型定义为你想支持的操作的记录。 在这种情况下,只有一个。
(作为奖励,从中可以看出,"只读变量 "的可组合性很强!)