【发布时间】:2023-03-07 21:41:01
【问题描述】:
我有以下代码使用recursion-schemes 库:
{-# 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
有没有更好的方法来使用recursion-schemes 来实现reduceBy? alter 参数似乎很脆弱,cata 真的适合吗?我听说有些东西可以用ana 和cata 来实现。
【问题讨论】:
-
似乎您可以使用 catamorphism 来获取列表图,然后只需
fmap为每个组使用 catamorphism(实际上是折叠)。 -
更模块化的方式来应用
valueAlgebra?似乎是个好主意。现在我将代数传递给alter,它接受其教堂编码版本。而且解码很痛苦。