我有一个关于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
答案 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]