Generic lenses
Opened this issue · 5 comments
Looking at #30
There is a couple of suggestions
Type classes for lenses
class HasScheme a where
_scheme :: ALens' a (Maybe Scheme)
Using records instead
type AbsoluteURI =
{ scheme :: Maybe Scheme
, query :: Maybe Query
, hiePart :: HierarchicalPart
}
_scheme :: forall r a. Lens' { scheme :: a |r } a
_scheme = lens _.scheme _{ scheme = _ }
Using newtype around records
newtype AbsoluteURI = AbsoluteURI
{ scheme :: Maybe Scheme
... }
derive instance newtypeAbsoluteURI :: Newtype AbsoluteURI _
_scheme :: forall r n a rr. Newtype n r => RowCons "scheme" a r rr => Lens' n a
_scheme = _Newtype <<< prop "scheme"
@garyb @kritzcreek What do you think? I think the 3rd one preserves both typesafety and polymorphic behaviour w/o introducing new entities.
Yeah, I did consider switching to newtypes-of-records when I was working on this but I didn't want to break the API yet again just now.
I'd probably just have _AbsoluteURI = _Newtype
, etc. lenses then, and let them be composed with a general _scheme
.
Oh! I see the differences between approaches. If there is generic lens from newtype to query type that effectively means that all uris have the same implicit type. And when there is _AbsoluteURI
that means that those things are different entities with different types.
That's another question: why uri can't be implemented as pathy using phantoms? I mean phantoms around newtyped records.
The URI type variations have more differences than just the path type - some aren't allowed to have query/fragment, etc. All the stuff in here is based on the spec, so the encoding isn't always as natural as it might be, as I was trying to ensure validity in construction (which as it happens isn't right anyway, you can still construct invalid URIs directly if you really try).
The newtype/record approach didn't happen in the end as some more sum components were introduced that made it awkward, but we could still perhaps do something with the class approach for this if it's perceived to be painful enough still 😉
Is there still any desire for this? #50 re-introduces the newtype/record approach, by the way.