module Prairie.Fold where
import Control.Monad (foldM)
import Prairie.Class
import Data.List (foldl')
data SomeFieldWithValue rec where
SomeFieldWithValue :: Field rec a -> a -> SomeFieldWithValue rec
recordToFieldList :: forall rec. (Record rec) => rec -> [SomeFieldWithValue rec]
recordToFieldList :: forall rec. Record rec => rec -> [SomeFieldWithValue rec]
recordToFieldList rec
rec =
(SomeField rec -> SomeFieldWithValue rec)
-> [SomeField rec] -> [SomeFieldWithValue rec]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
(\(SomeField Field rec a
field) ->
Field rec a -> a -> SomeFieldWithValue rec
forall rec a. Field rec a -> a -> SomeFieldWithValue rec
SomeFieldWithValue Field rec a
field (Field rec a -> rec -> a
forall rec ty. Record rec => Field rec ty -> rec -> ty
getRecordField Field rec a
field rec
rec)
)
(forall rec. Record rec => [SomeField rec]
allFields @rec)
foldRecord
:: forall rec r
. (Record rec)
=> (forall ty. ty -> r -> Field rec ty -> r)
-> r
-> rec
-> r
foldRecord :: forall rec r.
Record rec =>
(forall ty. ty -> r -> Field rec ty -> r) -> r -> rec -> r
foldRecord forall ty. ty -> r -> Field rec ty -> r
k r
init rec
rec =
(r -> SomeFieldWithValue rec -> r)
-> r -> [SomeFieldWithValue rec] -> r
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'
(\r
acc (SomeFieldWithValue Field rec a
field a
value) ->
a -> r -> Field rec a -> r
forall ty. ty -> r -> Field rec ty -> r
k a
value r
acc Field rec a
field
)
r
init
(rec -> [SomeFieldWithValue rec]
forall rec. Record rec => rec -> [SomeFieldWithValue rec]
recordToFieldList rec
rec)
foldMRecord
:: forall rec m r
. (Record rec, Monad m)
=> (forall ty. ty -> r -> Field rec ty -> m r)
-> r
-> rec
-> m r
foldMRecord :: forall rec (m :: Type -> Type) r.
(Record rec, Monad m) =>
(forall ty. ty -> r -> Field rec ty -> m r) -> r -> rec -> m r
foldMRecord forall ty. ty -> r -> Field rec ty -> m r
k r
init rec
rec =
(r -> SomeFieldWithValue rec -> m r)
-> r -> [SomeFieldWithValue rec] -> m r
forall (t :: Type -> Type) (m :: Type -> Type) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM
(\r
acc (SomeFieldWithValue Field rec a
field a
value) ->
a -> r -> Field rec a -> m r
forall ty. ty -> r -> Field rec ty -> m r
k a
value r
acc Field rec a
field
)
r
init
(rec -> [SomeFieldWithValue rec]
forall rec. Record rec => rec -> [SomeFieldWithValue rec]
recordToFieldList rec
rec)
foldMapRecord
:: forall rec m
. (Record rec, Monoid m)
=> (forall ty. ty -> Field rec ty -> m)
-> rec
-> m
foldMapRecord :: forall rec m.
(Record rec, Monoid m) =>
(forall ty. ty -> Field rec ty -> m) -> rec -> m
foldMapRecord forall ty. ty -> Field rec ty -> m
k rec
rec =
(SomeFieldWithValue rec -> m) -> [SomeFieldWithValue rec] -> m
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: Type -> Type) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\(SomeFieldWithValue Field rec a
f a
v) -> a -> Field rec a -> m
forall ty. ty -> Field rec ty -> m
k a
v Field rec a
f) (rec -> [SomeFieldWithValue rec]
forall rec. Record rec => rec -> [SomeFieldWithValue rec]
recordToFieldList rec
rec)