Haskell中无需自定义函数,组合多foldr处理累加器类型的通用方法?
Haskell网格变换函数的标准替代方案
你写的gridFoldr本质是调整了foldr的参数顺序,让它返回Grid -> Grid类型的函数,从而能通过(.)组合操作。Haskell里有现成的标准方法,完全不需要自定义这个函数:
1. 用flip直接调整foldr参数顺序
foldr的类型是(a -> b -> b) -> b -> [a] -> b,你需要的是把后两个参数交换位置,得到(a -> Grid -> Grid) -> [a] -> Grid -> Grid的效果。借助flip函数就能直接实现:
-- 替代你的gridFoldr f args flip (foldr f) args
这样组合操作时可以直接写:
let grid' = flip (foldr gridOp1) args1 . flip (foldr gridOp2) args2 $ myGrid
2. 用Endo幺半群批量组合变换
如果需要组合多个网格操作,Data.Monoid中的Endo类型会更方便。Endo a专门用来包装a -> a的函数,它的mappend对应函数组合(.),mconcat可以批量组合多个操作:
import Data.Monoid (Endo(..), mconcat) let gridTransforms = [ Endo $ flip (foldr gridOp1) args1 , Endo $ flip (foldr gridOp2) args2 ] grid' = appEndo (mconcat gridTransforms) myGrid
这种方式在操作数量较多时,比链式的(.)更简洁易读。
关于Monad的说明
这里其实不需要用Monad,因为你要的是函数组合能力,而Grid -> Grid属于自同态函数,Endo幺半群正好对应这个场景,比Monad更轻量、贴合需求。
内容的提问来源于stack exchange,提问作者kubivan
相关产品推荐
相关产品推荐

