我有三个功能(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.单个组合列表与连接列表相同,因此我们可以替换concat为mconcat.
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文档.