У меня есть следующий код, используя 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
.
Похоже, вы могли использовать катаморфизм, чтобы получить карту списков, а затем просто «fmap» катаморфизм (на самом деле) для каждой группы. – danidiaz
Более модульный способ применения 'valueAlgebra'? Кажется хорошей идеей. Теперь я передаю алгебре «alter», которая принимает его версию, закодированную в церкви. И декодирование болезненно. – nponeccop