module Prairie.Traverse where
import Data.List (foldl')
import Prairie.Class
import Control.Applicative (liftA2)
import Prairie.Fold
traverseRecord
:: forall rec f. (Record rec, Applicative f)
=> (forall ty. ty -> Field rec ty -> f ty)
-> rec
-> f rec
traverseRecord :: forall rec (f :: Type -> Type).
(Record rec, Applicative f) =>
(forall ty. ty -> Field rec ty -> f ty) -> rec -> f rec
traverseRecord forall ty. ty -> Field rec ty -> f ty
f rec
init =
(f rec -> SomeFieldWithValue rec -> f rec)
-> f rec -> [SomeFieldWithValue rec] -> f rec
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' f rec -> SomeFieldWithValue rec -> f rec
k (rec -> f rec
forall a. a -> f a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure rec
init) (rec -> [SomeFieldWithValue rec]
forall rec. Record rec => rec -> [SomeFieldWithValue rec]
recordToFieldList rec
init)
where
f' :: Field rec ty -> ty -> f (SomeFieldWithValue rec)
f' :: forall ty. Field rec ty -> ty -> f (SomeFieldWithValue rec)
f' Field rec ty
field ty
val =
Field rec ty -> ty -> SomeFieldWithValue rec
forall rec a. Field rec a -> a -> SomeFieldWithValue rec
SomeFieldWithValue Field rec ty
field (ty -> SomeFieldWithValue rec)
-> f ty -> f (SomeFieldWithValue rec)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> ty -> Field rec ty -> f ty
forall ty. ty -> Field rec ty -> f ty
f ty
val Field rec ty
field
k :: f rec -> SomeFieldWithValue rec -> f rec
k f rec
frec (SomeFieldWithValue Field rec a
field a
val) =
(SomeFieldWithValue rec -> rec -> rec)
-> f (SomeFieldWithValue rec) -> f rec -> f rec
forall a b c. (a -> b -> c) -> f a -> f b -> f c
forall (f :: Type -> Type) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
(\(SomeFieldWithValue Field rec a
field' a
val') rec
rec -> Field rec a -> a -> rec -> rec
forall rec ty. Record rec => Field rec ty -> ty -> rec -> rec
setRecordField Field rec a
field' a
val' rec
rec)
(Field rec a -> a -> f (SomeFieldWithValue rec)
forall ty. Field rec ty -> ty -> f (SomeFieldWithValue rec)
f' Field rec a
field a
val)
f rec
frec