Skip to content

Instantly share code, notes, and snippets.

@techtangents
Last active December 18, 2015 06:08
Show Gist options
  • Save techtangents/5737508 to your computer and use it in GitHub Desktop.
Save techtangents/5737508 to your computer and use it in GitHub Desktop.
RE: benkolera: Even though it makes your DSL shiny-ish, overloading functions is a PitA to a FP library user. Please use a sum type instead. #bad #scala etorreborre: @benkolera I'm clearly guilty of this but I don't quite get why it is so bad. Pointers?
Let's use Scala as the implementation language.
Say you have an API function setFoo, that is overloaded for Chook and Dog.
One might call it either of these ways:
setFoo(chook)
setFoo(dog)
As an API user, I wish to call this function from another function
def q(c: Chook) {
somefn()
setFoo(c)
}
But, what if this function doesn't know whether it wants to set a Chook or a Dog?
I either have to overload or sum-type and switch.
e.g. 1
def q(c: Chook) {
somefn()
setFoo(c)
}
def q(d: Dog) {
somefn()
setFoo(d)
}
e.g. 2
sealed trait ChookOrDog
case class IsChook(c: Chook) extends ChookOrDog
case class IsDog(d: Dog) extends ChookOrDog
def q(cd: ChookOrDog) {
somefn()
cd match {
case IsChook(c) => setFoo(c)
case IsDog(d) => setFoo(d)
}
}
And... since setFoo is overloaded, each overload has to handle the separate cases of Chook and Dog somehow.
It may end up looking very much like 'q' in example 2, or the Chook or Dog classes would have a common
trait that it would use. In the first case you would be using a sum type internally anyway, so you might
as well take the sum type as a parameter. In the second case, you are making use of the trait to convert
the input type to something else - as such, you should just accept the trait type directly (using
inheritance), or as an implicit (typeclass instance).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment