Haskell:修改数组特定索引处的值

Haskell:修改数组特定索引处的值,haskell,functional-programming,Haskell,Functional Programming,哈斯克尔是新来的。我已经创建了一个char数组,我正试图找出在给定特定索引的情况下修改该数组中数据的最佳方法 我已经创建了一个数组,我正在将它传递到我的main中的以下方法中。那部分很好用。我只是不知道如何在每个索引中操作数据。在这种特殊情况下,如果满足以下条件,则我将尝试重写该值。我想把它放回我的主板上,这样我就可以打印出更新过的主板了 import System.Random import Control.Monad import Data.Array import Data.List m

哈斯克尔是新来的。我已经创建了一个char数组,我正试图找出在给定特定索引的情况下修改该数组中数据的最佳方法

我已经创建了一个数组,我正在将它传递到我的main中的以下方法中。那部分很好用。我只是不知道如何在每个索引中操作数据。在这种特殊情况下,如果满足以下条件,则我将尝试重写该值。我想把它放回我的主板上,这样我就可以打印出更新过的主板了

import System.Random
import Control.Monad
import Data.Array
import Data.List

modifyArray :: Array Int Char -> Int -> IO (Array Int Char)
modifyArray arr i =
    if i > 0 then
        if i `mod` 102 == 1 then do
            (MODIFY ARRAY AT INDEX:i to equal ' ')
        else modifyArray arr (i-1)
    else arr   

实际上,您不需要修改数组。只需让您的函数创建一个具有所需更改的新数组,如下所示:

modifyArray :: Array Int Char -> Int -> Array Int Char
modifyArray arr i =
    if i > 0 then
        if i `mod` 102 == 1 then
            arr // [(i, ' ')]
        else modifyArray arr (i-1)
    else arr   

Data.Array
包含
/
操作符,这意味着“取左边的数组,应用右边的更改,然后返回结果”。此外,由于此函数不执行任何IO,因此无需在类型签名中使用“do”或具有IO。

如果您计划只更新阵列几次,则可以使用,如所述

但是,如中所述,如果您想频繁更新阵列,这不是很有效:

注意,
/
可能是O(n),因为它必须遍历列表(就像命令式程序一样)。如果你需要大量变异,你可以使用
MArray
MVector

因此,这意味着对于大型阵列,更新阵列可能需要一些时间,因为每次更新都会生成原始阵列的副本,并修改该特定值

这是一种特殊的类型。因此,我们可以使用以下内容定义
modifyArray


如果你想改变数组的值,最好考虑一个<代码> MARLY (可变数组),而不是一个<代码>数组>代码>,因为<代码>数组>代码>将导致一个拷贝。谢谢Jo,使用MayLay-Wrar会更难以置信的高效吗?但即便如此,你所做的事情似乎规模很小,不会有太大的区别,而且会增加很多复杂性,特别是对于新手来说。
modifyArray :: IOArray Int Char -> Int -> IO (IOArray Int Char)
modifyArray arr idx | i < 0 = return arr
                    | mod i 102 == 1 = writeArray arr idx ' ' >> return arr
                    | otherwise = modifyarr arr idx
modifyArray :: IOArray Int Char -> Int -> IO (IOArray Int Char)
modifyArray arr idx | i < 0 = return arr
                    | otherwise = writeArray arr (idx - mod (idx-1) 102) ' ' >> return arr