scala – 折叠flatMap /绑定在函数列表(a.k.a. Name Combinator
在编写简单的RPN计算器的过程中,我有以下类型的别名:
type Stack = List[Double] type Operation = Stack => Option[Stack] …我写了一个好奇的Scala代码: val newStack = operations.foldLeft(Option(stack)) { _ flatMap _ } 这需要一个初始的值堆栈,并将一个操作列表应用于堆栈.每个操作可能会失败(即产生一个Option [Stack]),所以我用flatMap进行排序.这个有点不寻常的事情(在我看来)是我折叠在一个单一的功能列表上,而不是折叠数据列表. 我想知道是否有一个标准函数捕获这种“折叠绑定”行为.当我试图玩“组合名称”游戏时,Hoogle通常是我的朋友,所以我在Haskell中尝试了同样的精神锻炼: foldl (>>=) (Just stack) operations 这里的类型是: foldl :: (a -> b -> a) -> a -> [b] -> a (>>=) :: Monad m => m a -> (a -> m b) -> m b 所以我的神秘折叠(>> =)组合器的类型在将折叠类型和(>> =)排成一行之后应该是: mysteryCombinator :: Monad m => m a -> [a -> m a] -> m a …这又是我们所期望的.我的问题是,使用该类型的功能搜索Hoogle不会产生任何结果.我尝试了一些其他排列,我认为可能是合理的:a – > [a – > m a] – > m a(即以非单值开始),[a – > m a] – > m a – > m(即参数翻转),但也没有运气.所以我的问题是,有没有人知道我的神秘“折叠绑定”组合器的标准名称? 解决方法
a – > m a只是一个Kleisli箭头,参数和结果类型都是一个.
Control.Monad.(>=>)组成两个Kleisli箭:
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c 想想翻转(.),但是Kleisli箭头而不是功能. 所以我们可以把这个组合器分为两部分,组合和“应用”: composeParts :: (Monad m) => [a -> m a] -> a -> m a composeParts = foldr (>=>) return mysteryCombinator :: (Monad m) => m a -> [a -> m a] -> m a mysteryCombinator m fs = m >>= composeParts fs 现在,(> =>)和flip(.)在更深的意义上与仅仅是类似相关;函数箭头( – >)和包装Kleisli箭头Kleisli的数据类型都是Control.Category.Category的实例.所以如果我们要导入该模块,我们实际上可以将composeParts重写为: composeParts :: (Category cat) => [cat a a] -> cat a a composeParts = foldr (>>>) id (>>>)(在Control.Category中定义)只是一种更好的写作方式作为翻转(.). 所以,我没有标准的名字,但它只是组成一个功能列表的一般化.标准库中有一个Endo类型,包含 – > a并有一个Monoid的实例,其中mempty是id,mappend是(.);我们可以将其推广到任何类别: newtype Endo cat a = Endo { appEndo :: cat a a } instance (Category cat) => Monoid (Endo cat a) where mempty = Endo id mappend (Endo f) (Endo g) = Endo (f . g) 然后我们可以将composeParts实现为: composeParts = appEndo . mconcat . map Endo . reverse 这只是mconcat.与一些包装反向.然而,我们可以避免相反的情况,因为实例使用(.)而不是(>>>),通过使用双重Monoid,它只是将一个monoid转换成一个与翻转的mappend: composeParts :: (Category cat) => [cat a a] -> cat a a composeParts = appEndo . getDual . mconcat . map (Dual . Endo) 这表明composeParts在某种意义上是一个“明确定义的模式”:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |