concatMap做什么?

时间:2011-03-07 21:20:35

标签: haskell

concatMap做什么? 我知道concatmap做了什么。它们只是放在一起还是完全不同的功能?

3 个答案:

答案 0 :(得分:20)

是的,concatMap功能只是concatmap放在一起。由此得名。将函数放在一起只是意味着组合它们:

(.) :: (b -> c) -> (a -> b) -> a -> c

但由于concat的类型签名,mapmap无法通过简单地使用函数组合放在一起:

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

这使它与列表monad的=<<函数相同:

concatMap :: (a -> [b]) -> [a] -> [b]

=<< :: Monad m => (a -> m b) -> m a -> m b

现在你知道关于concatMap的所有信息。仅concat应用于map的结果。因此这个名字。

答案 1 :(得分:12)

概念上是,但actual implementation不同:

concatMap               :: (a -> [b]) -> [a] -> [b]
concatMap f             =  foldr ((++) . f) []

答案 2 :(得分:8)

检查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! "