Purescript 中的变异状态
Mutating state in Purescript
我刚开始学习 Purescript,希望这不是一个愚蠢的问题。
假设我们有一个对象
a = {x:1,y:2}
我们想将 x 更改为等于 2。据我所知,如果我们使用 ST monad,则必须复制整个对象才能更改值。如果初始对象很大,这将是非常低效的。就地改变对象的正确方法是什么?
ST
monad 是一个很好的方法,但根据您的用例,可能有也可能没有为此的标准库函数。
purescript-maps
中的 Data.StrMap
模块为具有字符串键的同类记录定义了一个外部类型,因此如果您的值都具有相同的类型,您可以使用 Data.StrMap.ST
来改变您的记录到位。
如果没有,您应该能够轻松定义一个函数来使用 ST
和 FFI 就地更新记录。棘手的一点是选择正确的类型。如果你想为特定的键做一些事情,你可以写一个函数
setFoo :: forall r a h eff. STRef h { foo :: a | r } -> a -> Eff (st :: ST h | eff) Unit
例如。在不失去类型安全的情况下定义泛型 setter 会更加困难。这是 Data.StrMap
做出的权衡:您将自己限制为单一值类型,但可以使用任意键。
我刚开始学习 Purescript,希望这不是一个愚蠢的问题。
假设我们有一个对象
a = {x:1,y:2}
我们想将 x 更改为等于 2。据我所知,如果我们使用 ST monad,则必须复制整个对象才能更改值。如果初始对象很大,这将是非常低效的。就地改变对象的正确方法是什么?
ST
monad 是一个很好的方法,但根据您的用例,可能有也可能没有为此的标准库函数。
purescript-maps
中的 Data.StrMap
模块为具有字符串键的同类记录定义了一个外部类型,因此如果您的值都具有相同的类型,您可以使用 Data.StrMap.ST
来改变您的记录到位。
如果没有,您应该能够轻松定义一个函数来使用 ST
和 FFI 就地更新记录。棘手的一点是选择正确的类型。如果你想为特定的键做一些事情,你可以写一个函数
setFoo :: forall r a h eff. STRef h { foo :: a | r } -> a -> Eff (st :: ST h | eff) Unit
例如。在不失去类型安全的情况下定义泛型 setter 会更加困难。这是 Data.StrMap
做出的权衡:您将自己限制为单一值类型,但可以使用任意键。