如何在Haskell中映射多个参数的函数列表?

use*_*967 6 haskell currying

我有三个功能(getRow,getColumn,getBlock)使用两个参数(x和y),每个产生相同类型的列表.我想写第四个连接输出的函数:

outputList :: Int -> Int -> [Maybe Int]
outputList x y = concat . map ($ y) $ map ($ x) [getRow,getColumn,getBlock]
Run Code Online (Sandbox Code Playgroud)

该功能有效,但有没有办法将双地图(三个'$')重写为一个地图?

dav*_*420 23

import Data.Monoid

outputList :: Int -> Int -> [Maybe Int]
outputList = mconcat [getRow, getColumn, getBlock]
Run Code Online (Sandbox Code Playgroud)

你应该得到解释.

首先,我将明确指出所有这些函数都具有相同的类型.

outputList, getRow, getColumn, getBlock :: Int -> Int -> [Maybe Int]
Run Code Online (Sandbox Code Playgroud)

现在让我们从您的原始定义开始.

outputList x y = concat . map ($ y) $ map ($ x) [getRow,getColumn,getBlock]
Run Code Online (Sandbox Code Playgroud)

这些函数导致a [Maybe Int],并且任何事物的列表都是monoid.单个组合列表与连接列表相同,因此我们可以替换concatmconcat.

outputList x y = mconcat . map ($ y) $ map ($ x) [getRow,getColumn,getBlock]
Run Code Online (Sandbox Code Playgroud)

另一个是monoid的东西是一个函数,如果它的结果​​是一个monoid.也就是说,如果b是幺半群,那么a -> b它也是幺半群.单调组合函数与使用相同参数调用函数相同,然后单独组合结果.

所以我们可以简化到

outputList x = mconcat $ map ($ x) [getRow,getColumn,getBlock]
Run Code Online (Sandbox Code Playgroud)

然后再来

outputList = mconcat [getRow,getColumn,getBlock]
Run Code Online (Sandbox Code Playgroud)

我们完成了!


Typeclassopedia有一个关于幺半部分,尽管在这种情况下,我不知道它补充说,大有超越了Data.Monoid文档.