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
```