Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Type class that combines RefType and Validate #193

Closed
wants to merge 16 commits into from

Conversation

fthomas
Copy link
Owner

@fthomas fthomas commented Jul 26, 2016

This adds the RefinedType type class that combines RefType and Validate instances for a refined type F[T, P]. The motivating example for this type class was given by @benhutchison on Gitter. Abstracting over RefType.applyRef currently requires a lot of type ceremony:

def refineEff[S] = new ApplyRefPartiallyAppliedExt[S]

final class ApplyRefPartiallyAppliedExt[S] {
  def apply[E: Err, F[_, _], T, P](t: T)(
    implicit ev: F[T, P] =:= S, rt: RefType[F], v: Validate[T, P]
  ): Eff[E, S] =
    fromXor(RefType.applyRef[S].apply(t).toXor)
}

The goal is to allow calls like refineEff[PosInt](5) where PosInt is an alias for Int Refined Positive and the base type Int can be inferred from the parameter of apply. With RefinedType, this can be simplified to:

def refineEff[S] = new ApplyRefPartiallyAppliedExt[S]

final class ApplyRefPartiallyAppliedExt[S] {
  def apply[E: Err, T](t: T)(
    implicit rt: RefinedType.AuxT[S, T]
  ): Eff[E, S] =
    fromXor(rt.refine(t).toXor)
}

What has improved with RefinedType:

  • apply has two fewer type parameters
  • apply has two fewer implicit parameters
  • RefType.applyRef[S].apply(t) became rt.refine(t)

In general I think this is a win. The only downside is that we still require the ApplyRefPartiallyAppliedExt class to partially apply the refined type S and to let the base type T be inferred.

Also the combination of RefType and Validate is very common (e.g., type class instances of 3rd-party libraries for refined types almost always require the combination of these two), so it is natural to combine them. It also makes the implementation of refined simpler in some cases.

It is unfortunate that the names RefType and RefinedType are very similar. This type class makes me regret the name RefType. Maybe something like CarrierType or WrapperType would have been a better choice.

@codecov-io
Copy link

codecov-io commented Jul 26, 2016

Current coverage is 98.51% (diff: 95.00%)

Merging #193 into master will decrease coverage by 0.47%

Powered by Codecov. Last update c15e4b9...7090c69

@benhutchison
Copy link

+1. Much simpler. Im keen to try it out in a project!

@fthomas
Copy link
Owner Author

fthomas commented Dec 16, 2017

Superseded by #369 which also contains the RefinedType type class.

@fthomas fthomas closed this Dec 16, 2017
@fthomas fthomas deleted the topic/RefinedType branch December 17, 2017 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants