Haskell 不带 Lens 的可变字段结构

Mutable field structure in Haskell without Lens

我想写一个生成结构体的函数 具有可变值的字段。

本来我是用TypeScript写的,代码如下:

const Foo = <A>(a: A) =>
  ({
    x: a,             //mutable
    y: someFunction   //mutable
  });

基本上,x 的类型始终是 A,而 yA -> A 即使它们是可变的。

我只需要一个简单的 setter 和 getter 函数来改变字段,最好只使用 ST-monad 并且不想依赖 [=16 这样的库=].

到目前为止我发现的最接近的东西是 ST 可变数组 Data.Array.MArray,但这个是针对数组而不是结构的。

您推荐什么简单的智能方法?

如果您定义如下结构:

data Foo a = Foo {
    bar :: a,
    qux :: a -> a
}

然后你可以定义一个对象:

myFoo :: Foo Int
myFoo = Foo 2 id

并创建一个经过轻微修改的副本:

myFoo2 :: Foo Int
myFoo2 = myFoo { bar = 4 }

因此您可以在 STRef to work with a reference that is updated then with modifySTRef 中使用它,例如:

myST :: ST s (Foo Int)
myST = do
    ref <- newSTRef (Foo 2 id)
    modifySTRef ref (\x -> x { bar = 4 })
    readSTRef ref

因此您可以 运行 使用 runST myST。例如,我们可以在评估 ST s (Foo Int):

之后打印 bar
ghci> print (bar (runST myST))
4