我使用recursion-schemes
库下面的代码:RamdaJS reduceBy()在Haskell使用递归的方案
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeFamilies #-}
import Data.Functor.Foldable
import Data.Maybe
import qualified Data.Map as M
reduceBy valueAlgebra keyFn = cata $ fooAlgebra valueAlgebra keyFn
fooAlgebra
:: Ord k =>
(ListF t a -> a) -> (t -> k) -> ListF t (M.Map k a) -> M.Map k a
fooAlgebra valueAlgebra keyFn = \case
Nil -> M.empty
Cons elt acc -> M.alter
(Just . (valueAlgebra . Cons elt) . fromMaybe (valueAlgebra Nil))
(keyFn elt)
acc
用作let countBy = reduceBy (\case Nil -> 0 ; Cons a b -> succ b) id in countBy [42,5,5,8,8,8]
。代码模仿http://ramdajs.com/docs/#reduceBy
有没有更好的方法来实现reduceBy
使用recursion-schemes
? alter
论据看起来很脆弱,而且cata
真的很合适吗?我听说有些东西可以实现为ana
和cata
。
好像你可以使用catamorphism来获取列表的映射,然后只是'fmap'每个组的catamorphism(折叠,真的)。 – danidiaz
一个更模块化的方式来应用'valueAlgebra'?似乎是一个好主意。现在我将代数传递给'alter',它接受它的教会编码版本。解码是痛苦的。 – nponeccop