我的目標是接受一個輸入,如:
[(8, P1) 。(8, P2), (10, P3) ]
然后把它變成這樣:
[(8, [P1, P2]), (10, P3) ]
鑒于像8和10這樣的數字是資料型別Time(包裝和Int),而P1和P2是資料型別Person(包裝了一個String)。這是我到目前為止所做的:
groupTogether :: [(Time, Person)] -> [(Time, Person) ]
groupTogether [] = []
groupTogether ((x, y) : (a, b) : ks)
| x == a = (x, (y : (b)) : groupTogether ks
|否則 = (x, y) : groupTogether ((a, b) : ks)
而且它 "有點 "作業,但通常輸出是像(8, Name1Name2)而不是(8, [Name1, Name1])。而且我不知道一旦串列中只有一個元素,該函式應該怎么寫。它說缺少一個 "exaustive pattern"。我做錯了什么?如果我試圖用:把元素放在一起,代碼就無法運行。
uj5u.com熱心網友回復:
這樣如何? (注意Foldable t可以被認為是一個串列)
% ghci
λ> :m Data.Map。
λ> data P = P1| P2 | P3 deriving (Eq, Ord, Show)
λ> let input = [(8, P1], (8, P2), (10, P3) ] 。 : [(Int, P)
λ> :typePrelude.foldl>。
_ :: 可折疊 t => (b -> a -> b) -> b -> t a -> b
λ> :type Prelude. foldl (mp (k, p) -> insertWith (<>) k [p] mp)
_ :: (Foldable t, Ord k) => Map k [a] -> t (k, a) -> Map k [a]
λ> :type Prelude. foldl (mp (k, p) -> insertWith (<>) k [p] mp) Mempty
_ :: (Foldable t, Ord k) => t (k, a) -> Map k [a]
λ> :type Prelude. foldl (mp (k, p) -> insertWith (<>) k [p] mp) Mempty input
_ :: Map Int [P]
λ> Prelude.foldl (mp (k, p) -> insertWith (<>) k [p] mp) Mempty input
fromList [(8, [P2, P1], (10,[P3])]
λ> toList (Prelude.foldl (mp (k, p) -> insertWith (<> ) k [p] mp) mempty input)
[(8,[P2,P1]),(10,[P3] ]
uj5u.com熱心網友回復:
這個呢?
這個呢?
import Data.List
import Data.Function。
data P = P1| P2 | P3 deriving Show
x = [(8, P1], (8, P2), (10, P3) ]
fun list = let lists = groupBy ((==) `on` fst) x -- [[(8,P1),(8,P2)],[(10,P3)]
nums = map (fst . head) lists -- [8,10]/span>
ps = (map . map) snd lists -- [[P1,P2],[P3]]
in zip nums ps -- [(8,[P1,P2]),(10,[P3]) ]
在lists中,我通過數字的相等性對專案進行了分組,在nums中,我提取了每個組中所有專案共同的數字,在ps中,我通過(map . map) . snd提取了那些P*的東西,不管它們是什么,通過兩個函式層應用snd。
注意,如果在一般情況下,x中數量相等的專案不一定相鄰(在你的例子中,它們是相鄰的),你可能想在使用groupBy之前對串列進行排序,使用一個適當的排序演算法,正如下面的評論中所建議的。
至于你想要的輸出
[(8, [P1, P2]), (10, P3) ]
這根本不可能得到,因為在Haskell中一個串列的所有元素都有相同的型別,但是(8, [P1, P2])和(10, P3)有不同的型別,即(時間,[Person])和(時間,Person)。這已經被你問題下的一些評論所暗示,但你還沒有糾正你的問題(你應該)。在我的回答中,我已經假定你的意思是寫[(8, [P1, P2]), (10, [P3])]。
至于你的嘗試
groupTogether :: [(Time, Person)] -> [(Time, Person) ]
groupTogether [] = []
groupTogether ((x, y) : (a, b) : ks)
| x == a = (x, (y : (b)) : groupTogether ks
|否則 = (x, y) : groupTogether ((a, b) : ks)
有幾個語法的問題:
- 簽名是錯誤的,因為它表明輸出與輸入具有相同的型別;這當然是可能的,但是沒有反映出(經過糾正的)期望的輸出;可能你的意思是寫
groupTogether :: [(Time, Person)] -> [(Time, [Person])]/code> groupTogether [] = []處理一個空的串列輸入,而groupTogether ((x, y) : (a, b) : ks)處理一個兩個或更多元素的串列輸入,但是沒有辦法處理一個單子串列,這正是 "exaustive pattern missing" 錯誤所暗示的;- 由于
y和b具有相同的型別,Person,運算式y : (b)是不正確的,因為它相當于y:b,而:希望在左邊有一個a,在右邊有一個[a];你可能想把它改為y:[b],或者是[y,b]; - 以類似的方式,
y在otherwise情況下應該是[y]。
然而,即使你應用了上面的修正,仍然會有一些地方不太正確。請看這個:
groupTogether ((x, y) : (a, b) : ks)
| x == a = (x, y : [b]) : groupTogether ks
你正在對串列中的前兩對進行模式匹配,并將它們放在一個單一的對中,但是如果ks中的第一對有另一個a作為它的第一個元素呢?你要把它留在ks中,而不是把它與其他兩個元素分組。這要么是錯誤的,要么是從你的問題的文本中不清楚的,在這種情況下,你應該改進它。
。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/316947.html
標籤:
