是的,其實你可以把它寫成一個列表理解聲明,並使用模式,而不是匹配:
result = [ h | (h:_) <- ll ]
或作爲一個函數:
heads :: [[a]] -> [a]
heads ll = [ h | (h:_) <- ll ]
所以在這裏,我們使用匹配所有非空列表的模式(h:_)
,我們直接獲得此列表的頭部h
並將其添加到列表中。如果您在列表理解中使用模式(在左側的箭頭<-
的左側,它將跳過與模式不匹配的元素)。
這也比使用length
更安全的,因爲length
會卡住進入無限循環,如果你是無限名單的工作。此外,通過在非全部函數上使用模式,我們有更多的句法保證這個函數將起作用(是的,一旦非空元素被過濾,我們當然確定head
不會導致錯誤,但是我們只知道這是因爲我們有關於head
函數的信息)。
請注意,由於您使用if
而沒有then
和else
部分,因此您的嘗試將導致語法錯誤。
或者,我們可以像@DanielWagner說,不同的使用寫heads
功能,比如:
heads :: [[a]] -> [a]
heads ll = concatMap (take 1) ll
,或者使用列表單子的綁定:
heads :: [[a]] -> [a]
heads = (take 1 =<<)
或我們可以調換2d列表。在這種情況下,第一行包含列表的所有頭部。由於不能保證有這樣的行,所以我們可以在末尾附加一個空列表,如:
heads :: [[a]] -> [a]
heads = head . (++ [[]]) . transpose
你想爲空列表發生什麼?只是過濾/忽略它?爲什麼過濾器不能做你想要的? – puhlen
過濾器僅刪除空列表,但我想使用'head'並在head元素上執行一些操作。 –
但是一個空的列表沒有頭。你需要那個地圖+濾鏡不能做什麼?如果你只關心兩次迭代列表,它不會。這些行動是懶惰評估的。 – puhlen