I am trying to do a heterogeneous fold over a record with values having Either
s. The rows of the record represent input values in a form. They are either Right
indicating a successfully captured value or Left
indicating error. So {field1: Right "good"}
or {field1: Left e}
. I wish to fold this structure, and flatten it into a record of Right { field1: "good", ... }
or a Left e
, if there is an error in any row encountered during the fold.
Maybe it is easier for you to read my attempt at the instance:
instance foldRight ::
(IsSymbol sym
, Row.Lacks sym r
, Row.Cons sym b r r') =>
FoldingWithIndex FilterFields (Proxy sym) (Either a { | r }) (Either a b) (Either a { | r' }) where
foldingWithIndex FilterFields k (Right rec) (Right b) = Right (Record.insert k b rec)
foldingWithIndex FilterFields k _ (Left a) = Left a
foldingWithIndex FilterFields k (Left a) (Right _) = Left a
foldRecord ::
forall a r1 r2.
HFoldlWithIndex FilterFields (Either a {}) (Either a { |r1 }) (Either a { | r2}) =>
Either a {|r1} ->
Either a {|r2}
foldRecord r = hfoldlWithIndex FilterFields ((Right {}) :: Either a {}) r
Unfortunately, the compiler groans with:
No type class instance was found for
Heterogeneous.Folding.HFoldlWithIndex FilterFields
(Either a4 (Record ()))
(Either a5 (Record r16))
(Either a5 (Record r27))
while applying a function hfoldlWithIndex
of type HFoldlWithIndex t0 t1 t2 t3 => t0 -> t1 -> t2 -> t3
to argument FilterFields
while inferring the type of hfoldlWithIndex FilterFields
in value declaration foldRecord
where a4 is a rigid type variable
bound at (line 0, column 0 - line 0, column 0)
r16 is a rigid type variable
bound at (line 0, column 0 - line 0, column 0)
r27 is a rigid type variable
bound at (line 0, column 0 - line 0, column 0)
a5 is a rigid type variable
bound at (line 0, column 0 - line 0, column 0)
t2 is an unknown type
t3 is an unknown type
t0 is an unknown type
t1 is an unknown type
[NoInstanceFound]
Has anyone achieved something like this?
Thanks in advance.