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 Selective applicative functors #2746

Closed
wants to merge 1 commit into from
Closed

Conversation

cb372
Copy link
Contributor

@cb372 cb372 commented Mar 8, 2019

This is a collaboration with @hamishdickson. Made a first stab at implementing Selective Applicative Functors as suggested in #2745.

  • Add Selective type class
  • Add instance for Validated
  • Start writing laws
  • Start writing combinators

Here is the "shapes" example from the paper using Validated:

scala> import cats._, cats.data._, cats.data.Validated._
import cats._
import cats.data._
import cats.data.Validated._

scala> type Radius = Int
defined type alias Radius

scala> type Width = Int
defined type alias Width

scala> type Height = Int
defined type alias Height

scala> :paste
// Entering paste mode (ctrl-D to finish)

sealed trait Shape
case class Circle(r: Radius) extends Shape
case class Rectangle(w: Width, h: Height) extends Shape

// Exiting paste mode, now interpreting.

defined trait Shape
defined class Circle
defined class Rectangle

scala> def shape[F[_]](x: F[Boolean], r: F[Radius], w: F[Width], h: F[Height])(implicit F: Selective[F]): F[Shape] =
  F.ifS(x)(F.map(r)(radius => Circle(radius): Shape))(F.applicative.map2(w, h){ case (width, height) => Rectangle(width, height): Shape })
shape: [F[_]](x: F[Boolean], r: F[Radius], w: F[Width], h: F[Height])(implicit F: cats.Selective[F])F[Shape]

scala> type V[A] = Validated[String, A]
defined type alias V

scala> import cats.instances.string._
import cats.instances.string._

scala> shape[V](valid(true), valid(1), invalid("width?"), invalid("height?"))
res1: V[Shape] = Valid(Circle(1))

scala> shape[V](valid(false), invalid("radius?"), valid(2), valid(3))
res2: V[Shape] = Valid(Rectangle(2,3))

scala> shape[V](valid(false), valid(1), invalid("width?"), invalid("height?"))
res3: V[Shape] = Invalid(width?height?)

scala> shape[V](invalid("choice?"), invalid("radius?"), valid(2), invalid("height?"))
res4: V[Shape] = Invalid(choice?)

This is a work in progress (see the TODO comments) but happy to receive feedback at this stage.

After getting this far, we're still not sure about whether it's better for Selective to extend Applicative or to have it as a member. We went for the latter, but it's a bit clumsy to work with.

* Add Selective type class
* Add instance for Validated
* Start writing laws
* Start writing combinators
cb372 added a commit to cb372/cats-selective that referenced this pull request Mar 24, 2019
cb372 added a commit to cb372/cats-selective that referenced this pull request Mar 25, 2019
@dwijnand
Copy link
Contributor

Close in favour of implementation ideas and experimentation in https://github.com/cb372/cats-selective and theoretical discussions in #2745?

@cb372
Copy link
Contributor Author

cb372 commented Apr 27, 2019

Sounds good to me. I really need to get back to work on that repo I started...

@cb372 cb372 closed this Apr 27, 2019
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.

2 participants