【问题标题】:Modifying elements of Haskell 2D array修改 Haskell 二维数组的元素
【发布时间】:2014-12-31 01:31:15
【问题描述】:

我正在编写一个函数来修改下面给出的给定二维“数组”的元素:

change_elem :: Int -> Int -> a -> [[a]] -> [[a]]
-- empty list case
change_elem _ _ _ [] = []

-- have arrived at the element to change`
change_elem 0 0 x ((y:ys):ls) = (x:ys):ls

-- reduce the column until we find the element to change
change_elem 0 col x ((y:ys):ls) = [[y]] ++ change_elem 0 (col-1) x (ys:ls)

-- reduce the row until we find the column to change
change_elem row col x (l:ls) = l : change_elem (row-1) col x ls

它适用于change_elem 1 0 3 [[1,2],[4,5]] 等输入并产生[[1,2],[3,5]]。但是,我的问题是当我尝试更改不在第 0 列中的元素时,因此问题显然在于“减少列”步骤。

change_elem 2 1 7 [[1,2,3],[4,5,6],[1,2,0]] 给出输出 [[1,2,3],[4,5,6],[1],[7,0]]。它的行为是将给定行的较早元素分成单例列表。

change_elem 0 4 10 [[0,1,2,3,4,5,6]] 产生[[0],[1],[2],[3],[10,5,6]]

(++) 运算符不应该将较早的元素返回到列表中,留下一个统一的行吗?

我曾尝试在结果列表上调用 concat,但是当我将行修改为:

... concat $ [[y]] ++ change_elem 0 (col-1) x (ys:ls)

我收到一个很长的错误,但这似乎应该有效。 错误:

Couldn't match expected type ‘[a]’ with actual type ‘a’
  ‘a’ is a rigid type variable bound by
      the type signature for
        change_elem :: Int -> Int -> a -> [[a]] -> [[a]]
      at test.hs:15:16
Relevant bindings include
  ls :: [[a]] (bound at test.hs:23:29)
  ys :: [a] (bound at test.hs:23:25)
  y :: a (bound at test.hs:23:23)
  x :: a (bound at test.hs:23:19)
  change_elem :: Int -> Int -> a -> [[a]] -> [[a]]
    (bound at test.hs:17:1)
In the expression: y
In the expression: [y]

【问题讨论】:

    标签: list haskell concatenation


    【解决方案1】:

    不,++ 运算符不会这样做。它只是将两个列表连接在一起。用[[1]] ++ [[2]],你可以说x = [1]y = [2],然后你有[x] ++ [y],这显然是[x, y],或者[[1], [2]]通过直接替换。

    至于解决您当前的问题,我建议编写一个可以替换简单列表中索引处的元素的函数,如

    replace :: Int -> a -> [a] -> [a]
    replace i x xs = ???
    

    那么你可以非常简单地实现change_elem as

    change_elem row col x xs =
        let row_to_replace_in = xs !! row
            modified_row = replace col x row_to_replace_in
        in replace row modified_row xs
    

    这当然不是最有效或最安全的实现,但它是一个非常简单的实现。

    您在使用concat 时看到该错误的原因是因为您将[[Int]] 类型的东西转换为[Int],但是您告诉编译器您的函数必须返回一些输入 [[Int]](当提供 Int 矩阵时)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-30
      相关资源
      最近更新 更多