如何在 Haskell 中保存列表可变值?
How to hold a list mutable values in Haskell?
我想要一个数组,比如:
myArray = [1,2,3,4,5,6,7,8,9]
并能够 运行 一个将列表中的值更改为另一个值的函数。我希望能够 运行 这个函数几次 myArray
在每次 运行.
之后更新到新的一组数字
myArray = [1,2,3,4,5,6,7,8,9]
>>> f 1 5 myAarray
>>> myArray
[1,2,3,4,1,6,7,8,9]
>>> f 3 8 myArray
>>> myArray
[1,2,3,4,1,6,7,3,9]
如何为我的值创建一个可以更改值的容器。
谢谢!
所有 Haskell 值都是不可变的。您不能更改绑定到名称的值(您可以在 GHCi 中 shadow 它们,但这是一个稍微不同的事情)。
如果你想实现 true1 可变性,你需要一个不可变的 reference 到可变数据。要使用它们,通常您需要处于单子上下文中。
下面是一个使用名为 IORef
:
的低级引用类型的示例
import Data.IORef
import Control.Monad
f :: [Int] -> [Int]
f = map (+1)
main = do
a <- newIORef [1,2,3,4,5]
readIORef a >>= print
readIORef a >>= (return . f) >>= writeIORef a
readIORef a >>= print
请注意,a
的值不会改变;它仍然指向相同的 "value location"。所指向的实际值发生了变化。
也就是说,这需要使用通常不受欢迎的 IO
monad。根据您的需要,像 State
这样的完全纯净的解决方案可能会更好。
-- assume previous f
g :: State [Int] ()
g = modify f
现在你只需要从一些状态开始,状态 monad 会为你链接修改,就像这样:
main = print $ execState (g >> g >> g) [1,2,3,4,5]
这本质上等同于简单的组合:
f . f . f $ [1,2,3,4,5]
最后但同样重要的是,这可能是您在 Haskell 中的默认首选解决方案。
P.S。我在示例中使用了更简单的 f
,但您没有理由不这样做:
(f 1 5) . (f 3 8) $ myArray
1这有点模棱两可,但为了简单起见,我将其扩展为 "the one that could be backed by direct memory operations"。
我想要一个数组,比如:
myArray = [1,2,3,4,5,6,7,8,9]
并能够 运行 一个将列表中的值更改为另一个值的函数。我希望能够 运行 这个函数几次 myArray
在每次 运行.
myArray = [1,2,3,4,5,6,7,8,9]
>>> f 1 5 myAarray
>>> myArray
[1,2,3,4,1,6,7,8,9]
>>> f 3 8 myArray
>>> myArray
[1,2,3,4,1,6,7,3,9]
如何为我的值创建一个可以更改值的容器。
谢谢!
所有 Haskell 值都是不可变的。您不能更改绑定到名称的值(您可以在 GHCi 中 shadow 它们,但这是一个稍微不同的事情)。
如果你想实现 true1 可变性,你需要一个不可变的 reference 到可变数据。要使用它们,通常您需要处于单子上下文中。
下面是一个使用名为 IORef
:
import Data.IORef
import Control.Monad
f :: [Int] -> [Int]
f = map (+1)
main = do
a <- newIORef [1,2,3,4,5]
readIORef a >>= print
readIORef a >>= (return . f) >>= writeIORef a
readIORef a >>= print
请注意,a
的值不会改变;它仍然指向相同的 "value location"。所指向的实际值发生了变化。
也就是说,这需要使用通常不受欢迎的 IO
monad。根据您的需要,像 State
这样的完全纯净的解决方案可能会更好。
-- assume previous f
g :: State [Int] ()
g = modify f
现在你只需要从一些状态开始,状态 monad 会为你链接修改,就像这样:
main = print $ execState (g >> g >> g) [1,2,3,4,5]
这本质上等同于简单的组合:
f . f . f $ [1,2,3,4,5]
最后但同样重要的是,这可能是您在 Haskell 中的默认首选解决方案。
P.S。我在示例中使用了更简单的 f
,但您没有理由不这样做:
(f 1 5) . (f 3 8) $ myArray
1这有点模棱两可,但为了简单起见,我将其扩展为 "the one that could be backed by direct memory operations"。