簡體   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