concatMap做什么?

Ahs*_*san 24 haskell

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

Aad*_*hah 21

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

(.) :: (b -> c) -> (a -> b) -> a -> c
Run Code Online (Sandbox Code Playgroud)

然而concatmap不能通过简单地使用函数组合物付诸因为类型签名一起map:

map :: (a -> b) -> [a] -> [b]
       --------    ---    ---
          a         b      c
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,函数组合需要一个类型的函数a -> b,但是map类型a -> b -> c.要编写concat,map您需要使用.:运算符:

(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
Run Code Online (Sandbox Code Playgroud)

concat函数的类型签名为:

concat :: [[a]] -> [a]
          -----    ---
            c       d
Run Code Online (Sandbox Code Playgroud)

因此concat .: map是类型:

concat .: map :: (a -> [b]) -> [a] -> [b]
                 ----------    ---    ---
                     a          b      d
Run Code Online (Sandbox Code Playgroud)

与以下内容相同concatMap:

concatMap :: (a -> [b]) -> [a] -> [b]
Run Code Online (Sandbox Code Playgroud)

.:操作本身可以写成函数组合方面:

(.:) = (.) (.) (.)

-- or

(.:) = (.) . (.)
Run Code Online (Sandbox Code Playgroud)

因此concatMap可以写成:

concatMap = (.) (.) (.) concat map

-- or

concatMap = (concat .) . map

-- or

concatMap = concat .: map
Run Code Online (Sandbox Code Playgroud)

如果你flip的参数concatMap得到>>=列表monad 的(bind)函数:

instance Monad [] where
    return x = [x]
    (>>=) = flip concatMap
    fail _ = []

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

>>= :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

这使它=<<与list monad 的功能相同:

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

=<< :: Monad m => (a -> m b) -> m a -> m b
Run Code Online (Sandbox Code Playgroud)

所以现在你知道了所有要知道的事情concatMap.它只concat适用于a的结果map.由此得名.


ken*_*ytm 13

从概念上说是的,但实际的实现是不同的:

concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f =  foldr ((++) . f) []
Run Code Online (Sandbox Code Playgroud)

  • 指出为什么使用`foldr`来实现`concatMap`可能是有用的,原因是使用`foldr / build`技术来进行捷径砍伐:https://ghc.haskell.org/trac/ghc/wiki / FoldrBuildNotes (2认同)

Ezr*_*zra 8

检查文档显示:

concatMap :: (a -> [b]) -> [a] -> [b]
Run Code Online (Sandbox Code Playgroud)

将函数映射到列表并连接结果

因此它的定义如下:

-- | Map a function over a list and concatenate the results.
concatMap               :: (a -> [b]) -> [a] -> [b]
concatMap f             =  foldr ((++) . f) []
Run Code Online (Sandbox Code Playgroud)

比较ghci的以下输出:

*Main> concatMap (++"! ") ["one", "two", "three"]
"one! two! three! "
*Main> concat $ map (++"! ") ["one", "two", "three"]
"one! two! three! "
Run Code Online (Sandbox Code Playgroud)

  • 此外,如果你想知道*为什么*它存在,我相信它是因为它是`>> =`的列表实现,只是给出了一个不同的名称.:) (4认同)