servant icon indicating copy to clipboard operation
servant copied to clipboard

Add `Capture` variant to specify needed instances directly

Open 3noch opened this issue 8 years ago • 3 comments

In my library I want to use a type from an upstream library in my API definition. Unsurprisingly the upstream library does not define ToHttpApiData or FromHttpApiData on its data types. This means I am left with two simple options: introduce orphan instances or wrap this type in a newtype. Orphans are...well orphans. Using a newtype would mean that my downstream users have to wrap/unwrap simply to tell servant about the proper instances of an otherwise unrelated data type. In situations like this I find myself wanting a variant of Capture that doesn't rely on the type's instances but allows you to directly specify which instances to use (perhaps via some other type). For example:

import Data.ISO3166_CountryCodes (CountryCode)
import Web.HttpApiData (FromHttpApiData)

newtype CountryCodeInstances a = CountryCodeInstances a
instance FromHttpApiData (CountryCodeInstances CountryCode) where
  -- ...

type Api = CaptureWith CountryCodeInstances "country-code" CountryCode :> Get '[PlainText] ()

3noch avatar Mar 09 '17 03:03 3noch

Actually, this same thing would be useful for response types as well. Perhaps there's a more general solution that would be useful in every case.

3noch avatar Mar 09 '17 04:03 3noch

Hmm, might work with Coercible connecting CountryCode and CountryCodeInstances

OTOH new combinator is never "free".

phadej avatar Mar 09 '17 07:03 phadej

Orphans are...well orphans

And worse than that: In libraries that are distributed, orphan instances "pollute" the instance space.

If you don't intend on distributing this library (internal project, etc), you can have those orphan instances.
Otherwise, maybe submit a PR to the country code library?

tchoutri avatar Dec 27 '21 16:12 tchoutri