繁体   English   中英

过滤列表列表中的元组[Haskell]

[英]Filter tuples in list of lists [Haskell]

我有一个元组列表的列表:

let list = [[(1,(2,2)),(0,(3,2)),(0,(4,2))],[(0,(2,3)),(0,(3,3)),(0,(4,3))],[(0,(2,4)),(0,(3,4)),(0,(4,4))]]

我想通过每个元组的第一个值过滤它们。 那就是我尝试过的

compute :: Matrix -> Coordinates -> Matrix
compute m (x,y) = filter (\(a,(_,_)) -> a /= 1) [row | row <- list]

type Matrix = [[Int]]
type Coordinates = (Int, Int)

那就是我得到的错误:

ContiguousRegion.hs:20:36:
Couldn't match expected type ‘[Int]’
            with actual type ‘(Integer, (t0, t1))’
In the pattern: (a, (_, _))
In the first argument of ‘filter’, namely
  ‘(\ (a, (_, _)) -> a /= 1)’
In the expression:
  filter
    (\ (a, (_, _)) -> a /= 1) [row | row <- checkAround m (x, y)]

ContiguousRegion.hs:20:58:
Couldn't match type ‘(Int, (Int, Int))’ with ‘Int’
Expected type: [Int]
  Actual type: [(Int, (Int, Int))]
In the expression: row
In the second argument of ‘filter’, namely
  ‘[row | row <- checkAround m (x, y)]’
Failed, modules loaded: none.

我该如何解决? 谢谢!

让我们采取一些步骤来简化compute功能并找出问题所在:

  1. 首先, [row | row <- list] [row | row <- list]不执行任何操作,仅等效于list ,因此我们可以将其删除并替换为list ,以使函数更易于阅读:

     compute m (x,y) = filter (\\(a,(_,_)) -> a /= 1) list 

    顺便说一句,在您的消息中,我看到list实际上不是要过滤的参数。 相反,它是一个checkAround m (x, y) ,因此compute可能看起来像这样:

     compute m (x,y) = filter (\\(a,(_,_)) -> a /= 1) $ checkAround m (x, y) 
  2. 您传递给filter的函数不必要地复杂,我们可以用\\(a,_) -> a /= 1甚至(/=1) . fst代替它(/=1) . fst (/=1) . fst使它减少噪音。 这样做给我们:

     compute m (x,y) = filter ((/=1) . fst) list 
  3. 我想说现在更容易发现问题了。 您的list的类型为[[(Int, (Int, Int))]] ,即。 这是元组列表的列表。

    但是您进入filter的谓词期望一个元组,因此filter本身期望一个元组列表。

    这是一个明显的类型不匹配。 我们该如何解决? 我不知道,这取决于您,但是我想您想过滤内部列表。

    我们如何做到这一点? 好吧,我们需要遍历每个内部列表,对其进行过滤,然后将过滤后的列表放入新列表中。 这正是map (或fmap )可以帮助我们的。 让我们将我们构建的过滤器映射到list

     compute m (x,y) = map (filter ((/=1) . fst)) list 
  4. 不幸的是,以上仍然给我们一个类型错误:

     Couldn't match type '(Integer, (Integer, Integer))' with 'Int' Expected type: [[Int]] Actual type: [[(Integer, (Integer, Integer))]] 

    好吧,为什么呢? 我们知道, Actual typelist的类型,也是过滤后的列表的类型,但是Expected type是什么,为什么它是[[Int]]

    答案在于您的类型签名Matrix -> Coordinates -> Matrix compute应该产生一个Int列表的列表,但是我们在过滤一些不同的东西。

在这一点上,我真的不知道您想做什么,所以我就在这里结束,但是我怀疑您要么需要更改compute的类型签名,要么需要以某种方式将m与过滤后的结果合并为创建一个新矩阵。

这是您要做什么?

type SparseMatrix = [Row]
type Row = [Element]
type Element = (Int, Coordinates)
type Coordinates = (Int, Int)

removeRowVal :: Row -> Int -> Row
removeRowVal row i = filter ((/= i).fst) row

removeSMVal :: SparseMatrix -> Int -> SparseMatrix
removeSMVal sm i = [removeRowVal row i | row <- sm]

即使您的list不是某种奇怪的稀疏矩阵表示形式,我也认为最终结果就是您所描述的。

问题1:您对compute定义是指list ,但是list不是参数。

问题2:如果将list更改为m代码是正确的,但是给出的类型签名不正确。

解:

list更改为m ,并且不给类型签名:

compute m (x,y) = filter (\(a,(_,_)) -> a /= 1) [row | row <- m]

现在问ghci类型签名应该是什么:

ghci> :t compute
compute
    :: (Eq a, Num a) => [(a, (t2, t3))] -> (t, t1) -> [(a, (t2, t3))]

现在您将看到type Matrix应定义为

type Matrix = [ (Int, (Int,Int) ]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM