I’m re-explaining the “Data Types a la Carte” paper in my learning repo. I’m also trying to teach (and learn by doing so) how to use VariantF and ultimately purescript-run to solve its problem.

Having read xgrommx’s code, which removes ValueF as a data type and reduces it to a smart constructor via pure…

…I’ve written this code:

Unfortunately, I’m not sure how to evaluate (add (value 1) (value 2)) to 3.

The run combinator let you evaluate your set of functors in terms of some Monad m. There’s no combinator currently equivalent to iter from your linked example. However it can easily be written in terms of Run.resume Left Right and you’d get the same thing. If you wanted to use run you would have to use Identity as your m.

I’ve been banging my head at this for the past hour, but still haven’t gotten it to work. Sigh…

I realized that Run.resume Left Right is the definition of Run.peel. With this code:

iter :: forall r a. (VariantF r a -> a) -> Run r a -> a
iter k = go
where
go m = case peel m of
Left f -> k (go <$> f)
Right a -> a
eval :: forall r a b
. ((VariantF () a -> b) -> VariantF r Int -> Int)
-> Run r a
-> Int
eval algebra = iter (case_ # algebra)
-- Examples
main :: Effect Unit
main = do
_ <- eval addAlgebra example_add
pure unit

I get a compiler error because eval expects the a type in its Run r a argument to be Int, not a. However, the a type in the add function is another Run (ADD + r) Int. I’m not sure how I’d fix that since the code should work if I wrapped another add in there (e.g. add example_add (value 5)