Hi,
I have record types with a parameter which might be Identity (for JSON encoding) or RemoteData (for partial representation in a structured UI editor).
I decided to define lenses/prisms for these types, because there are a lot of places use with them. A lens chain composed of precooked combinators breaks in the middle on fields with types such as f (Foo f)
.
I defined a class IsoPrism (I coined the name, because I don’t know the well known one)
class IsoPrism t a | t -> a where
_theVal :: Prism' t a
instance IsoPrism (Maybe a) a where
_theVal = _Just
instance IsoPrism (Identity a) a where
_theVal = prism' Identity (Just <<< unwrap)
With IsoPrism functions built on top the lenses could be f
polymophic:
setLearningRate :: forall f a.
IsoPrism (f a) a =>
ChartExprFilterBodyT f ->
ChartExprFilterBodyT f
setLearningRate = p .~ 0.5
where
p = _predicate <<< _theVal <<< _AcceptWithSvm <<<
_svmInputParams <<< _theVal <<< _XgBoost <<< _learningRate
but type checker requires a list of complicated constrains and makes less convenient:
setLearningRate :: forall f.
IsoPrism (f (ChartPredicateT f)) (ChartPredicateT f) =>
IsoPrism (f SvmInputParams) SvmInputParams =>
No type class instance was found for
Project.ChartPredicate.IsoPrism (f3 (ChartPredicateT f3)) (ChartPredicateT t4)
Some definitions mentioned the code above:
type ChartPredicate = ChartPredicateT Identity
type ChartExprFilterBodyT f =
{ predicate :: f (ChartPredicateT f)
}
_predicate :: forall a r. Lens' { predicate :: a | r } a
_predicate = lens _.predicate $ _ { predicate = _ }
_AcceptWithSvm :: forall f. Prism' (ChartPredicateT f) (SvmRuleT f)
_AcceptWithSvm =
prism' AcceptWithSvm $
case _ of
AcceptWithSvm b -> Just b
_ -> Nothing