【问题标题】:How can i solve this in haskell? [duplicate]我怎样才能在haskell中解决这个问题? [复制]
【发布时间】:2018-11-28 15:13:25
【问题描述】:

我得到这段代码来制作转置矩阵,但它不能 100% 正常工作。

type Mat a = [[a]]

transpose' :: Eq a => Mat a -> Mat a
transpose' [] = []
transpose' (h:t) = primelem (h:t):transpose' (eliminate' (h:t))

primelem :: Mat a -> [a]
primelem [] = []
primelem [[x]] = [x] 
primelem ((x:xs):t) = x : primelem t

eliminate' :: Eq a => Mat a -> Mat a
eliminate' [] = []
eliminate' (h:t) = (delete (head h) h):eliminate' t

*Main> transpose' [[1,2,3],[0,4,5],[0,06]]

[[1,0,0],[2,4,6],[3,5*** Exception:(..)Non-exhaustive patterns in function primelem

我想弄清楚,但我真的不知道缺少哪个案例。

【问题讨论】:

  • 请提供一个更有用的问题标题。
  • 这种方法是非常错误的。转置矩阵应该只是在位置上操纵元素,而不考虑它们的值,但delete 使用元素的值。
  • 您正在寻找的答案是:[[1,2,3],[0,4,5],[0,06]] 中缺少逗号。
  • @WillNess 是的,我的错误,我已经放了一个逗号,但仍然是同样的错误。有人在这里发布了另一种执行此转置功能的方法
  • @deceze 抱歉,第一次来

标签: haskell


【解决方案1】:

要发现您遗漏了哪些情况,您应该使用-Wall 标志打开警告,如下面的 GHCi 会话所示。

> :set -Wall
> type Mat a = [[a]]
> :{
| primelem :: Mat a -> [a]
| primelem [] = []
| primelem [[x]] = [x] 
| primelem ((x:xs):t) = x : primelem t
| :}

<interactive>:5:1: warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for ‘primelem’: Patterns not matched: ([]:_)

<interactive>:7:14: warning: [-Wunused-matches]
    Defined but not used: ‘xs’

因此,您缺少的情况是:

primelem ([]:t) = ...

【讨论】:

  • 我仍然无法解决它,因为在矩阵中所有行都有数字,所以第一行不可能是空列表
  • @tbotl 不,您收到的错误消息表明您确实在运行时遇到了这种情况。
  • @tbotl 最初,是的,确实如此。但是你的最后一行只有两列,而其他行有三列(显然你忘记了逗号)。因此,在删除两列后,我们得到一个“矩阵”,其中包含两行非空行和最后一个空行,从而触发错误。
【解决方案2】:

你想多了。空列表的列表是它自己的转置。

transpose m | all null m = []
            | any null m = error "Not a matrix"

否则,将每个列表的第一个元素作为转置的第一行,将剩余的矩阵转置为其余的转置。

transpose m = map head m : transpose (map tail m)

这个函数实际上是完全的,只在那些实际上不是矩阵的列表中失败。它在非矩阵值上失败的事实有点令人毛骨悚然:

> transpose [[1,2], [3]]
[[1,3]*** Exception: Not a matrix
CallStack (from HasCallStack):
  error, called at tmp.hs:3:28 in main:Main

如果您想更干净地处理无效矩阵,请改为返回 Maybe (Mat a)

transpose :: Mat a -> Maybe (Mat a)
transpose m | all null m = Just []
            | any null m = Nothing
            | otherwise  = ((map head m):) <$> transpose (map tail m)

【讨论】:

  • 对于它的价值,库中的transpose 函数确实适用于“锯齿状矩阵”,跳过丢失的条目。例如。 transpose [[1,2],[3],[4,5]] = [[1,3,4],[2,5]]。关于该功能是有用还是有害,我不确定。
  • 我想说这是transpose :: [[a]] -&gt; [[a]]transpose :: Mat a -&gt; Mat a 之间的细微差别;后者应努力保持Mat a 确实是有效矩阵类型的意图,而不是暴露type 别名提供的泄漏抽象。
猜你喜欢
  • 2019-04-10
  • 2013-10-24
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 2020-11-28
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
相关资源
最近更新 更多