Skip to content

Conversation

@jozic
Copy link
Contributor

@jozic jozic commented Feb 15, 2018

motivation: Left and Right constructors are typed as Left and Right respectively, but sometimes we want something like Option.empty which returns None but typed as Option.

The test represents a code that would not compile if plain Left/Right constructors are used

@SethTisue please take a look

@scala-jenkins scala-jenkins added this to the 2.13.0-M4 milestone Feb 15, 2018
@SethTisue
Copy link
Member

LGTM in a general way, but I haven't worked in a codebase that makes especially heavy use of Either. I asked for feedback on gitter (https://gitter.im/typelevel/general?at=5a85d126ce68c3bc748f61d4)

@SethTisue
Copy link
Member

what's the value over just doing simple type ascription? e.g. Left(3): Either[Int, String]

@jozic
Copy link
Contributor Author

jozic commented Feb 15, 2018

the value is that no type ascription is needed :) same as Option.empty[Int] vs None: Option[Int],
code (subjectively) looks a little bit less cluttered without required type ascription
otherwise it's same

@SethTisue
Copy link
Member

@tpolecat points out that:

having to repeat the inferable type when you specify the non-inferable one is kind of a grunt

have you considered ways of avoiding that...?

@jozic
Copy link
Contributor Author

jozic commented Feb 15, 2018

the only way I know is already mentioned in gitter, like

implicit class LeftOps[A](a: A) extends AnyVal { def left[B]: Either[A,B] = Left[A,B](a) }

but I share your concern on selling it, though that would be awesome i think )

@LukaJCB
Copy link

LukaJCB commented Feb 15, 2018

To get a precise type with something like this (where Nothing never gets inferred), we could use the partiallyApplied trick, so something like this:

object Either {
  def left[A]: FromLeftPartiallyApplied[A] = 
    new FromLeftPartiallyApplied[A]

  def right[A]: FromRightPartiallyApplied[A] = 
    new FromRightPartiallyApplied[A]
}

class FromLeftPartiallyApplied[A](val dummy: Boolean = true) 
  extends AnyVal {
    def apply[B](b: B): Either[B, A] = Left(b)
  }

class FromRightPartiallyApplied[A](val dummy: Boolean = true) 
  extends AnyVal {
    def apply[B](b: B): Either [A, B] = Right(b)
  }

This means we can now use it like this: Either.right[String](42) and return a fully formed Either[String, Int] :)

This technique is described here: https://typelevel.org/cats/guidelines.html#partially-applied-type-params

@SethTisue
Copy link
Member

@jozic has now also submitted a version of @LukaJCB's suggestion for consideration over at #6329

@SethTisue
Copy link
Member

closing this one since no one has objected to #6329

@SethTisue SethTisue closed this Apr 25, 2018
@SethTisue SethTisue removed this from the 2.13.0-M4 milestone Apr 25, 2018
@SethTisue
Copy link
Member

having to repeat the inferable type when you specify the non-inferable one is kind of a grunt

even if #6329 isn't accepted, I would suggest we not accept this one either on this grounds, actually. but I think #6329 has a good chance

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.

4 participants