Yesterday I wrote a Stack Overflow answer about using Shapeless for generic derivation of
type class instances, and this morning I started putting together some
new documentation for circe's generic derivation, and after a few
paragraphs I decided that it might make sense to write a blog post that could serve as a bridge
between the two—between simple examples like the one in my answer (which doesn't really go into
motivation, etc.) and the kinds of things we're doing in circe. I'll start more or less from
scratch, assuming only some basic familiarity with Scala syntax.
Continue reading
Suppose we've got a simple representation of a user:
case class User(id: Long, name: String, email: String)
Now suppose we're writing a web service where we allow clients to post some
JSON to a resource to create a new user. We get to pick the id
, not the client,
so we might accept something like this:
{
"name": "Foo McBar",
"email": "foo@mcbar.com"
}
If we're using a type class-based JSON library like Argonaut, we'll
probably have written a codec instance for User
(or we may be using a library
like argonaut-shapeless that derives instances for our
case classes automatically).
The problem is that our User
codec won't work on JSON like the
example above (since it's missing the id
field).
Continue reading
It's not unusual in Scala to want to take a collection with items of some
algebraic data type and partition its elements by their constructors. In
this Stack Overflow question,
for example, we're given a type for fruits:
sealed trait Fruit
case class Apple(id: Int, sweetness: Int) extends Fruit
case class Pear(id: Int, color: String) extends Fruit
The goal is to be able to take a collection of fruits and split it into two
collections—one of apples and one of pairs.
def partitionFruits(fruits: List[Fruit]): (List[Apple], List[Pear]) = ???
It's pretty easy to use collect
to solve this problem for particular cases.
It's a little trickier when we start thinking about what a more generic version
of such a method would look like—we want to take a collection of items of some
arbitrary algebraic data type and return a n-tuple whose elements are
collections of items of each of that ADT's constructors (and let's require them
to be typed as specifically as possible, since this is Scala). It's not too hard
to imagine how you could write a macro that would perform this operation, but
it'd be messy and would probably end up feeling kind of ad-hoc (at least without
a lot of additional work and thinking).
Fortunately we've got Shapeless 2.0,
where Miles Sabin and co. have written the macros for us so we can keep our
hands clean.
Continue reading
Scala provides lexicographic Ordering
instances for
TupleN
types when all of the element types have Ordering
instances.
It doesn't provide the same instances for case classes, however—probably
just because lexicographic order isn't what you want for case classes as
often as it is for tuples.
Sometimes you actually do want a lexicographic ordering
for your case classes, though, and Scala unfortunately doesn't provide any nice
boilerplate-free way to create such orderings. This post will provide a
quick sketch of two approaches to filling this gap: one using macros, and
one using Shapeless 2.0's new Generic
machinery
and the TypeClass
type class.
First for a case class to use as a running example, along with some instances:
case class Foo(x: Int, y: String)
val a = Foo(9, "x")
val b = Foo(1, "z")
val c = Foo(9, "w")
val foos = List(a, b, c)
Let's quickly confirm that there's no Ordering[Foo]
already sitting around:
scala> foos.sorted
<console>:14: error: No implicit Ordering defined for Foo.
foos.sorted
^
Yep, we're going to have to take care of this ourselves.
Continue reading
I began writing this post as an answer to this Stack Overflow question about
learning how to use Shapeless,
but it ended up a little long for a Stack Overflow answer, so I'm posting it here instead.
When I first started teaching myself type-level programming in the context of Shapeless last year,
I spent a lot of time working through simple problems with heterogeneous lists of type-level natural numbers.
One fairly straightforward (but still non-trivial)
example of such a problem is the second user story of this Coding Dojo kata,
which is also outlined by Paul Snively in
this email to the Shapeless mailing list.
The goal is to determine whether a list of numbers is the appropriate length (nine) and has a valid checksum, which is calculated by taking the sum of each element multiplied by its distance (plus one) from the end of the list, modulo eleven.
Continue reading
People say that Validation
is Scalaz's gateway drug,
which might be accurate if you ignore the suggestion that there's
anything even remotely fun about validation. In my book, making sure that
your program doesn't choke on bad input is always a chore.
Applicative validation is at least a step in the right direction—it makes it easier to
write less code, introduce fewer bugs, and draw clearer lines
between data models and validation logic. Suppose for example that we have the
following case class in Scala:
case class Foo(a: Int, b: Char, c: String)
Suppose also that we have a form with three fields that we want to use to
create instances of Foo
. We receive input from this form as
strings, and we want to be sure that these strings have certain properties.
Continue reading