替换列表中的元素

时间:2019-05-15 15:12:23

标签: haskell

我有一个关于haskell中列表的简单问题。 (我是Haskell的初学者)

我会知道如何替换数组中的元素,但要尽可能简单。

[1, 2, 4, 4, 5]

[1, 2, 3, 4, 5]

还有如何在列表中出现数字

[1, 2, 3, 4]

[1, 2, 3, 4, 5]

我已经阅读了该教程:http://learnyouahaskell.com/starting-out

我在想第一个问题:

array = [1, 2, 4, 4, 5]
array[2] = 2

第二个:

array = [1, 2, 3, 4]
array ++ [5]

Ps:array ++ [5]与ghci一起工作,但是当我在代码中这样做时:

array = [1, 2, 3, 4]

modifyarray = do
print $ array !! 2
array ++ [5]
print $ array !! 4

那是行不通的...

编辑:

module Main where

import Lib
import System.Environment
import System.Exit

redPoint = [3,4,2]

fillArray file x = do
    let line = lines file
    print $ line

replaceAt x y = map (\(i,v) -> if (i==x) then y else v) . zip [1..]

replaceArray = do
    print $ redPoint !! 2
    replaceAt 2 9 redPoint
    print $ redPoint !! 2

openfile a n path = do
    file <- readFile path
    fillArray file 0
    replaceArray

exit = exitWith ExitSuccess
error_exit = exitWith (ExitFailure 84)

parse [a, n, path] = openfile a n path >> exit
parse [] = error_exit

main = do
    getArgs >>= parse

此错误:

  

无法将类型“ []”与“ IO”匹配         预期类型:IO整数           实际类型:[整数]       •在“ do”块的stmt中:replaceAt 2 9 redPoint         在表达式中:           确实打印$ redPoint! 2              replaceAt 2 9 redPoint              打印$ redPoint! 2         在“ replaceArray”的方程式中:             replaceArray               =打印$ redPoint! 2                    replaceAt 2 9 redPoint                    打印$ redPoint! 2

4 个答案:

答案 0 :(得分:4)

您不会在列表上进行突变,而是从给定列表中创建一个新列表。

一个示例,没有任何错误处理...

> replaceAt x y = map (\(i,v) -> if (i==x) then y else v) . zip [1..]
> replaceAt 3 10 [1..5]

[1,2,10,4,5]

通过将计数数字压缩来创建索引列表,编写映射函数以更改所需索引处的值。

答案 1 :(得分:1)

镜头! (也许是开销,但无论如何)

_drop 0 = id
_drop n = _tail . _drop (n - 1)

用例

[1..5] & _drop 1 %~ (5:) -- [1,5,2,3,4]

答案 2 :(得分:0)

使用镜头

> import Control.Lens

Control.Lens> [1..5] & (ix 1) .~ 5
[1,5,3,4,5]

答案 3 :(得分:0)

首先,请在一个帖子中只问一个问题。

这是一个不使用Lens的实现,更适合初学者。 replaceAt函数错误处理需要一些脑力劳动。没有错误处理,它可以放在一行中。

这些函数也可以在无限列表上使用。 replaceAt的执行时间取决于 i 。由于Haskell列表的递归性质,在列表末尾替换元素比在开始处慢。

module ListOperations where

replaceAt :: Int -> a -> [a] -> [a]
replaceAt i x xs = case (i<0, splitAt i xs) of
  (False,(start,(_:end))) -> start ++ (x:end)
  _                       -> error "Index out of bounds"

append :: a -> [a] -> [a]
append x xs = xs ++ [x]