You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If we want to perform a fold over an Expr we have to do a little dance with HRecWitness, deconstructing it recursively.
showE'::Pure#Expr->String
showE' = fold \caseHRecSelf->\caseExprLit i ->show i
ExprAnn (Const e) (Const t) -> e <>" : "<> t
HRecSub (HWitnessW_Expr_Expr) HRecSelf->\caseExprLit i ->show i
ExprAnn (Const e) (Const t) -> e <>" : "<> t
HRecSub (HWitnessW_Expr_Type) HRecSelf->\caseTypeUnit->"()"TypeAnn (Const t) (Const k) -> t <>" : "<> k
...
One can mechanically derive a GADT representing the closure of the HWitness
relation, which makes defining these folds much more pleasant:
withWitnessClosure
::foralletpa. (Recursively (WitnessClosuree) e)
=> (HWitnessClosureet->t#p->a)
->HRecWitnesset->t#p->a
withWitnessClosure f =Proxy@(WitnessClosuree) ##>> f inClosure
typeWitnessClosure::HyperType->HyperType->ConstraintclassWitnessClosureetwhereinClosure::HWitnessClosureetinstanceWitnessClosureExprExprwhere inClosure =EinstanceWitnessClosureExprTypewhere inClosure =TinstanceWitnessClosureExprKindwhere inClosure =KtypeHWitnessClosure::HyperType->HyperType->Data.Kind.TypedatafamilyHWitnessClosureabdatainstanceHWitnessClosureExprawhereE::HWitnessClosureExprExprT::HWitnessClosureExprTypeK::HWitnessClosureExprKind-- Used thusly:showE::Pure#Expr->String
showE =
fold
( withWitnessClosure \caseE->\caseExprLit i ->show i
ExprAnn (Const e) (Const t) -> e <>" : "<> t
T->\caseTypeUnit->"()"TypeAnn (Const a) (Const b) -> a <>" : "<> b
K->\caseKindStar->"*"
)
Does this construct have a place in hypertypes, or is this actually quite an
unidiomatic way of performing such a fold?
It seems like defining a Showable class and writing instances for Expr, Type and Kind might be the "proper" way to go? Something like:
typeShowable::HyperType->ConstraintclassShowablehwhereshow'::h#ConstString->StringinstanceShowableExprwhere
show' =\caseExprLit i ->show i
ExprAnn (Const e) (Const t) -> e <>" : "<> t
instanceShowableTypewhere
show' =\caseTypeUnit->"()"TypeAnn (Const a) (Const b) -> a <>" : "<> b
instanceShowableKindwhere
show' =\caseKindStar->"*"showE'::Pure#Expr->String
showE' = fold $Proxy@Showable##>> show'
The text was updated successfully, but these errors were encountered:
It seems like defining a Showable class and writing instances for Expr, Type and Kind might be the "proper" way to go?
Yes, that's how I usually do it.
Another theoretical benefit of this approach is that if there was another expression language typed with Type, or another type language kinded with Kind, then you would have reused for the show' implementations rather than repeating in the cases.
That being said, I can definitely see the ergonomic usefulness of your GADT approach. If there was a TH generator for it then one would need to do less work in cases like these and it would make using the library easier. It's kind of a flattened version of HRecWitness, and reminds me of join too. It would definitely be useful to have :)
Take for example, this language of literals, type-annotated expressions and
kind annotated types.
If we want to perform a fold over an
Expr
we have to do a little dance withHRecWitness
, deconstructing it recursively.One can mechanically derive a GADT representing the closure of the
HWitness
relation, which makes defining these folds much more pleasant:
Does this construct have a place in
hypertypes
, or is this actually quite anunidiomatic way of performing such a fold?
It seems like defining a
Showable
class and writing instances forExpr
,Type
andKind
might be the "proper" way to go? Something like:The text was updated successfully, but these errors were encountered: