I don't like the PartialIsoEnumerableWithCtx type much; it probably can be simplified ...
-- | An Iso that is not necessarily surjective; as well as takes an (unchanging)-- context value.typePartialIsoEnumerableWithCtxctxsa=(ctx->a->s,ctx->s->Maybea,ctx->[a])partialIsoIsLawfulForCtx::Eqa=>PartialIsoEnumerableWithCtxctxsa->ctx->BoolpartialIsoIsLawfulForCtx(to,from,getas)ctx=all(\a->lets=toctxainJusta==fromctxs)(getasctx)defaultEnum::(Boundedr,Enumr)=>[r]defaultEnum=[minBound..maxBound]
Haha, I'm literally working on such typeclass right now with @Asad Saeeduddin:big_smile:
What you want is Apply part of Applicative on n-ary functor, with different monoidal categories used for every type parameter ((Hask, (,), ()) and (Hask, Either, Void) instead of just (Hask, (,), ()) used in Applicative)
It's this hypothetical category of Haskell types and functions between them - doesn't really matter here, basically what I'm saying is that you can combine arbitrary types wrapped in your functor by tupling:
merge::fa->fb->f(a,b)
which is the same thing as
(<*>)::f(a->b)->fa->fb
just expressed differently
Similarly, in case of different functor you may combine these with sum:
merge::fa->fb->f(Eitherab)
which is suspiciously similar to
choose::(a->Eitherbc)->fb->fc->fa
except that Decidable lives in "opposite" category of Hask, where functions go the opposite way (as in Contravariant)
All of this stuff doesn't really matter - instead, at some point you should be able to just implement derive some MonoidalN class on Site and specialize it's method to get siteMerge
Getting close to getting things working (composing Emanote, and extending it, as example). Mostly works, with some edges cases (how some routes are decoded in Emanote).
Overall, there is progress in composable sites in Ema ... BUT still not happy. I can't compose the model creator/updater process easily (I can compose it, but it is a lot of leg work). I suspect the use of LVar (TMVar) is getting in the way.
I should look into continuations. Can they be composed more easily?
dataRoute=Route_Index|Route_Aboutderivingstock(Show,Eq,GHC.Generic)derivinganyclass(Generic,HasDatatypeInfo,IsRoute,HasModel)main::IO()main=void$Ema.runSite@Route()instanceRenderAssetRoutewhererenderAssetenc()r=Ema.AssetGeneratedEma.Html$tailwindLayout(H.title"Basic site">>H.base!A.href"/")$H.div!A.class_"container mx-auto"$doH.div!A.class_"mt-8 p-2 text-center"$docaserofRoute_Index->do"You are on the index page. "routeElemRoute_About"Go to About"Route_About->dorouteElemRoute_Index"Go to Index"". You are on the about page. "whererouteElemr'w=H.a!A.class_"text-red-500 hover:underline"!routeHrefr'$wrouteHrefr'=A.href(fromString.toString$Ema.routeUrlenc()r')
minimal site, no routes - but just to get a dynamic model going for use elsewhere:
dataRoutederivingstock(Show,Eq,Generic)derivinganyclass(SOP.Generic,SOP.HasDatatypeInfo)deriving(IsRoute)via(ConstModelRouteModelRoute)dataModel=ModelinstanceRenderAssetRoutewhererenderAsset_enc=\caseinstanceHasModelRoutewhererunModel__()=dopure$pureModel-- <-- make this non-pure to update the model
@TheMatten I ended up dropping the type class entirely and put the encoders in the
Site
typeimage.png
https://github.com/srid/ema/pull/81/files
I don't like the
PartialIsoEnumerableWithCtx
type much; it probably can be simplified ...Where I'm at ...
This is like Semigroup, but with polymorphic type indexes (r a).
Working version of that function!
https://github.com/srid/ema/blob/1e7318e929e28c7444e488089ce52d87e1c187db/src/Ema/Site.hs#L78-L123
Gotta heavily refactor. Wonder if any of the existing ideas would be useful to simplify this definition and implementation?
image.png
https://stackoverflow.com/q/71180949/55246
/cc @TheMatten
I have got something that's correct ... BUT not very elegant at all. https://github.com/srid/ema/pull/81
Sridhar Ratnakumar said:
Haha, I'm literally working on such typeclass right now with @Asad Saeeduddin :big_smile:
What you want is
Apply
part ofApplicative
on n-ary functor, with different monoidal categories used for every type parameter ((Hask, (,), ())
and(Hask, Either, Void)
instead of just(Hask, (,), ())
used inApplicative
)What's
Hask
here?Someone suggests
Data.Contravariant.Decidable
in Twitter: https://twitter.com/lucasdicioccio/status/1494902322861850625@sridca Looks like Data.Contravariant.Decidable in hiding.
- lucas卞dicioccio (@lucasdicioccio)Sridhar Ratnakumar said:
It's this hypothetical category of Haskell types and functions between them - doesn't really matter here, basically what I'm saying is that you can combine arbitrary types wrapped in your functor by tupling:
which is the same thing as
just expressed differently
Similarly, in case of different functor you may combine these with sum:
which is suspiciously similar to
except that
Decidable
lives in "opposite" category of Hask, where functions go the opposite way (as inContravariant
)All of this stuff doesn't really matter - instead, at some point you should be able to just
implementderive someMonoidalN
class onSite
and specialize it's method to getsiteMerge
Getting close to getting things working (composing Emanote, and extending it, as example). Mostly works, with some edges cases (how some routes are decoded in Emanote).
Overall, there is progress in composable sites in Ema ... BUT still not happy. I can't compose the model creator/updater process easily (I can compose it, but it is a lot of leg work). I suspect the use of LVar (TMVar) is getting in the way.
I should look into continuations. Can they be composed more easily?
Beneath the LVar abstraction, I already have something akin to continuations:
https://github.com/srid/unionmount/blob/c906d32c6e8d1b849e60680fd33d2af38fde309d/src/System/UnionMount.hs#L164-L168
m (initialValue, functionThatWillInformOfNewValues)
Alternatively I should think of Ema model updates as streams. Then it becomes a matter of composing streams.
Non-empty streams, more specifically (the initial value is readily available).
Composing callback-based updates using Applicative: image.png
I find myself going back to type class. Works well with generic composition.
Simplest site:
Just route type and HTML; everything else is boilerplate-free
minimal site, no routes - but just to get a dynamic model going for use elsewhere:
And what it looks to do the "virtual mount" on this model:
https://twitter.com/sridca/status/1502749766358380550
#Generics-based route encoding, among other things (composable sites!), is now functional. Just need to clean up the API now, which is not easy. Simplicity is hard. #Haskell https://twitter.com/sridca/status/1502749766358380550/photo/1
- 🍭 Hedone 🍭 (@sridca)https://stackoverflow.com/q/71475510/55246
@TheMatten What Ema apps look like right now. Uses
Prism'
for route encoding: https://github.com/fpindia/fpindia-site/blob/master/src/Main.hs@TheMatten Voila, https://srid.ca/ema-0.8
(Just remembered about conversation!)
Sridhar Ratnakumar said:
Looks great!