List Haskell-附加到列表列表中的列表,并返回更新的列表列表

List Haskell-附加到列表列表中的列表,并返回更新的列表列表,list,haskell,append,List,Haskell,Append,花了几个小时寻找将[[a]]转换成[[a]]]的方法,我认为这将是解决我问题的最好办法。问题包括将a附加到[a]并返回带有新更改的[[a]]] 例如:xs=[[a]、[b]、[c]和y=d 我想把y附加到xs!!0。我不能使用xs!!0++y因为它只返回[a,d],我知道这是因为Haskell的不变性 如何将值追加到子列表并返回列表列表?-[[a,d],[b],[c]]使用上面的示例来说明这一点。让zs中的{xs=[[1]];y=2;zs=[(xs!!0)+[y]}是在GHCi提示符下尝试的一个

花了几个小时寻找将
[[a]]
转换成
[[a]]]
的方法,我认为这将是解决我问题的最好办法。问题包括将
a
附加到
[a]
并返回带有新更改的
[[a]]]

例如:
xs=[[a]、[b]、[c]
y=d

我想把
y
附加到
xs!!0
。我不能使用
xs!!0++y
因为它只返回
[a,d]
,我知道这是因为Haskell的不变性


如何将值追加到子列表并返回列表列表?-<代码>[[a,d],[b],[c]]使用上面的示例来说明这一点。

让zs中的{xs=[[1]];y=2;zs=[(xs!!0)+[y]}是在GHCi提示符下尝试的一个示例

它返回
[[1,2]]

对于例如
[[1],[2,3],[4]]
之类的情况,我们可以这样做

appendToFirst :: [[a]] -> a -> [[a]]
appendToFirst (xs:r) y  =  (xs ++ [y]) : r
所以

> appendToFirst [[1],[2,3],[4]] 0
[[1,0],[2,3],[4]]
等号左边的
(xs:r)
是一个图案

等号右侧的
(:)
中的
(…):r)
是一个“
cons
”操作,一个数据构造函数,
(:)::t->[t]

xs
绑定到输入列表的“头”,即其第一个元素,
r
绑定到模式中输入列表的其余部分;因此,
xs
的值用于创建列表的更新版本,第一个子列表通过在其末尾添加值进行更改,
r
保持原样

xs++[y]
创建新实体、新列表,而
xs
y
继续引用它们定义为的相同旧值。因为Haskell的值和变量是不可变的,正如您所提到的


<>编辑:如果你想在中间的一些子列表的末尾添加新的元素,而不是上面所示的第一个元素,这可以用例如<代码> SPLITAT < /C>函数,如

appendInTheMiddle :: Int -> a -> [[a]] -> [[a]]
appendInTheMiddle i y xs  =  
     let
        (a,b) = splitAt i xs
     in
        init a ++ [last a ++ [y]] ++ b
试一试:

> appendInTheMiddle 2 0 [[1],[2],[3],[4]]
[[1],[2,0],[3],[4]]
如果希望添加基于0的错误处理、边界检查和调整索引(顺便说一句,这将导致更简单、更快的代码),则留给读者作为练习

在语法上,这可以通过“视图模式”进行简化,如下所示


我如何调整它,以便可以使用指针在xs中的任意点追加y(如您所称)?所以将y附加到xs!!n并返回xs。我曾尝试将其改为(q:xs:r)和类似的组合,但结果并不一致,因为它适用于丙戊酸钠值。谢谢(好的,我在答案中加了这个:)(谢谢!工作完美,解释得很好:))
{-# LANGUAGE ViewPatterns #-}

appendInTheMiddle :: Int -> a -> [[a]] -> [[a]]
appendInTheMiddle i y (splitAt i -> (a,b))  =
        init a ++ [last a ++ [y]] ++ b