concatMap
是做什麼用的? 我知道concat
和map
做什麼。它只是將它們放在一起還是完全不同的功能?concatMap是做什麼的?
回答
從概念上講,是的,但actual implementation不同的是:
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f = foldr ((++) . f) []
指出爲什麼'concatMap'是使用'foldr'實現的,原因是short-使用'foldr/build'技術減少森林砍伐:https://ghc.haskell.org/trac/ghc/wiki/FoldrBuildNotes – 2014-11-23 08:40:22
檢查the documentation顯示:
concatMap :: (a -> [b]) -> [a] -> [b]
地圖功能在一個列表並且將結果連接
而且其定義如下:
-- | Map a function over a list and concatenate the results.
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f = foldr ((++) . f) []
比較下面的輸出ghci的:
*Main> concatMap (++"! ") ["one", "two", "three"]
"one! two! three! "
*Main> concat $ map (++"! ") ["one", "two", "three"]
"one! two! three! "
此外,如果你想知道*爲什麼它存在,我相信這是因爲它是列表實現'>> =',只是給了一個不同的名字。 :) – porges 2011-03-07 22:01:29
是的,concatMap
功能只是concat
和map
放在一起。由此得名。將功能一起僅僅意味着將它們組成:
(.) :: (b -> c) -> (a -> b) -> a -> c
然而concat
和map
不能簡單地使用函數組合放在因爲map
類型的簽名一起:
map :: (a -> b) -> [a] -> [b]
-------- --- ---
a b c
正如你所看到的功能組成預期a -> b
類型的函數,但map
類型爲a -> b -> c
。要撰寫concat
與map
您需要使用.:
操盤手:
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
的concat
函數的類型簽名:
concat :: [[a]] -> [a]
----- ---
c d
因此concat .: map
的類型爲:
concat .: map :: (a -> [b]) -> [a] -> [b]
---------- --- ---
a b d
與concatMap
相同:
concatMap :: (a -> [b]) -> [a] -> [b]
的.:
運營商本身在功能構成方面來寫:
(.:) = (.) (.) (.)
-- or
(.:) = (.) . (.)
因此concatMap
可以寫爲:
concatMap = (.) (.) (.) concat map
-- or
concatMap = (concat .) . map
-- or
concatMap = concat .: map
如果flip
的concatMap
參數你得到的>>=
(綁定)函數列表monad:
instance Monad [] where
return x = [x]
(>>=) = flip concatMap
fail _ = []
flip concatMap :: [a] -> (a -> [b]) -> [b]
>>= :: Monad m => m a -> (a -> m b) -> m b
這使得相同的列表單子的=<<
功能:
concatMap :: (a -> [b]) -> [a] -> [b]
=<< :: Monad m => (a -> m b) -> m a -> m b
所以,現在你知道的一切,有了解concatMap
。這只是concat
適用於map
的結果。由此得名。
優秀的答案。只是一個錯字:「**在**你翻轉[...]」應該是**如果**。 – YoTengoUnLCD 2018-03-03 19:26:44
- 1. 什麼「?」做?什麼是__FILE__?
- 2. 什麼是setDetailItem:做什麼?
- 3. 是什麼[popViewControllerAnimated];做?
- 4. 什麼是random.random做
- 5. 什麼是「javascript :;」做?
- 6. 什麼是「GCMRegsistrar.register」做
- 7. page.driver.reset是什麼!做?
- 8. 這是做什麼
- 9. 什麼是簡單的JavaScript做什麼
- 10. WinJS.strictProcessing()是做什麼的?
- 11. Rollapply:by.column是做什麼的?
- 12. 'printf -v'是做什麼的?
- 13. EventEmitter.call()是做什麼的?
- 14. 這是做什麼用的?
- 15. WorkflowApplicationInstance.Abandon()是做什麼的?
- 16. 'set - $ REPLY'是做什麼的?
- 17. wxPuts是做什麼的?
- 18. mysql_escape_string()是做什麼的?
- 19. Polymer.flush()是做什麼的?
- 20. IntentFilter是做什麼的?
- 21. AutoFac:PropertyWiringFlags.AllowCircularDependencies是做什麼的?
- 22. GL_COLOR_ATTACHMENT是做什麼用的?
- 23. pg_basebackup是做什麼的?
- 24. CMFCButton :: EnableFullTextTooltip是做什麼的?
- 25. 這是做什麼用的?
- 26. pixel.facebook.com是做什麼用的?
- 27. 「window.functionname && functionname()」是做什麼的?
- 28. getNextEntry()是做什麼的?
- 29. IIS7 - MaxProcesses是做什麼的?
- 30. 這是做什麼的?
它在行爲上與'concatMap f = concat不可區分。地圖f'。我不確定它在理論上也更有效率。我想這只是一個便利的組合。 – luqui 2011-03-07 22:53:11
@luqui因爲'concatMap'是使用'foldr'實現的,所以可以使用'foldr/build'技術進行優化。因此,它的效率更高:https://ghc.haskell.org/trac/ghc/wiki/FoldrBuildNotes – 2014-11-23 08:41:37