我想要一个阵列,比如说:
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]
如何为可以更改值的值创建持有者。
谢谢!
答案 0 :(得分:3)
所有Haskell值都是不可变的。您无法更改绑定到名称的值(您可以在GHCi中影子它们,但这有点不同)。
如果要实现真正的 1 可变性,则需要对可变数据进行不可变引用。要使用这些,通常您希望处于monadic环境中。
以下是使用名为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
的值不会改变;它仍然指向相同的价值位置&#34;。指出的实际价值有何变化。
话虽这么说,但这需要使用通常不赞成的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 这有些含糊不清,但为了简单起见,我将其扩展为可以由直接内存操作支持的那个&#34;。