background preloader

Type System

Facebook Twitter

Why Scala's "Option" and Haskell's "Maybe" types will save you from null. Cedric Beust makes a bunch of claims in his post on Why Scala's "Option" and Haskell's "Maybe" types won't save you from null, commenters say he doesn't get it and he says nobody has argued with his main points. So I thought I'd do a careful investigation to see what, if anything, is being missed. First, right off the top here: Scala has true blue Java-like null; any reference may be null. Its presence muddies the water quite a bit. But since Beust's article explicitly talks about Haskell he's clearly not talking about that aspect of Scala because Haskell doesn't have null.

I'll get back to Scala's null at the end but for now pretend it doesn't exist. Second, just to set the record straight: "Option" has roots in programming languages as far back as ML. Both Haskell's "Maybe" and Scala's "Option" (and F#'s "Option" and others) trace their ancestry to it. Now, to the post. First Objection Really? With Maybe/Option you just say that the map holds optional values. Save Me! Back to Beust Onward. Structural Typing. February 3, 2010 by Stephan Schmidt Structural typing in Scala is the way to describe types by their structure, not by their name as with other typing. Structural typing reduces coupling and the need for inheritance. In Java you would mainly use interfaces instead of structural typing. I go with the same examples as in “Scala Goodness: Compound types” so it’s easier to compare both solutions. scala> call(new Dog) Comes to you scala> call(new Cat) Doesn't bother You can also give your structural type a name with type aliasing: With the same classes from above we get: scala> call(new Cat) Doesn't bother scala> call(new Dog) Comes to you Both ways work with more than one method: Calling with a new dog results in: scala> callAndFeed(new Dog) Comes to you Eats Structural typing is very useful if you are not able to modify classes to make them implement a trait or interface or if you want to reduce coupling and increase reuse.

Class Dog extends Feedable with Callable instead of Scala glory! See also: Gist: 229163 - Demo of generalised type constraints in Scala 2.8- GitHub. Abstract Type Members versus Generic Type Parameters in Scala. Angle Brackets and Curly BracesAbstract Type Members versus Generic Type Parameters in Scalaby Bill VennersOctober 7, 2009 Summary In this blog, I attempt to answer a common question among Scala programmers: when would I opt to use an abstract type member instead of a generic type parameter in Scala API design? A common question asked by people learning Scala is how to decide between abstract type members and generic type parameters when you need to model an abstract type. For those unfamiliar with the difference, type parameters in Scala are similar to type parameters in Java, except instead of Java's angle brackets: interface Collection<T> { // ... } Scala uses square brackets: // Type parameter version trait Collection[T] { // ... } Abstract type members in Scala have no equivalent in Java. // Type member version trait Collection { type T // ... } In both cases, the abstract type can be made concrete in a subtype. // Type parameter version trait FixtureSuite[F] { // ... } Or this one:

Working around type erasure ambiguities « Michid’s Weblog. In an earlier post I already showed how to work around ambiguous method overloads resulting from type erasure. In a nut shell the following code wont compile since both overloaded methods foo erase to the same type. Scala: Java: It turns out that there is a simple though somewhat hacky way to work around this limitations: in order to make the ambiguity go away, we need to change the signature of foo in such a way that 1) the erasure of the foo methods are different and 2) the call site is not affected.

Here is a solution for Java: We can now call foo passing either a list of ints or a list of strings without ambiguity: This doesn’t directly port over to Scala (why?). Like this: Like Loading... Preserving Types and Differing Subclass Type Parameters.

Monads

Using generalized type constraints - How to remove code with Scala 2.8. I love removing code. More I remove lesser is the surface area for bugs to bite. Just now I removed a bunch of classes, made unnecessary by Scala 2.8.0 type system. Consider this set of abstractions, elided for demonstration purposes .. trait Instrumentcase class Equity(name: String) extends Instrumentabstract class FI(name: String) extends Instrumentcase class DiscountBond(name: String, discount: Int) extends FI(name)case class CouponBond(name: String, coupon: Int) extends FI(name) Well, it's the instrument hierarchy (simplified) that gets traded in a securities exchange everyday. Class Trade[I <: Instrument](id: Int, account: String, instrument: I) { def calculateNetValue(..) = def calculateValueDate(..) = } In real life a trade will have lots and lots of attributes.

Trade can have lots of methods which model the domain logic of the trading process, calculating the net amount of the trade, the value date of the trade etc. And use it as follows ..

Functional Data Structures

Existential Types. Type Classes. Level Programming in Scala « Apocalisp. This series is intended as a guided tour of some type-level programming I have done in Scala. It generally consists of code and examples with a few lines of explanation. It is usually assumed that the reader understands the features of Scala’s type system. This is not always a good assumption about either the author or the reader of course, so comments and questions are welcome. The series is in 10 parts, with some parts consisting of more than one post each. The present post will serve as a table of contents linking to the rest of the series, so bookmark this page for easy reference. Prior work/reference: All source code is available at Scala’s type system in 2.8 allows recursion, and infinite recursion at that, as demonstrated in [1,2].

Level Programming in Scala, Part 2: implicitly and =:= « Apocalisp. This post briefly introduces a useful technique for comparing types (shown to me by Jason Zaugg) that will be used to check the results of type-level computations later. It uses the ‘implicitly’ method, which is defined in Predef as: This is useful for capturing an implicit value that is in scope and has type T. The implicit that we want in this case is A =:= B for some types A and B. A =:= B will only be found when A is the same type as B. For example, this compiles: but this does not: Also available are <:< and <%< for type conformance and views, respectively. A conformance (<:<) example: A conversion (<%<) example: Note that when the compiler prints the <:< and <%< types, it doesn’t use infix notation. It has a bit of a hack to print full names if the simple name is ambiguous. Like this: Like Loading... Level Programming in Scala, Part 3: Boolean « Apocalisp.

A good introductory example to type-level programming is the Church encoding of booleans. It doesn’t require anything too fancy and we need booleans when comparing numbers later. If you are already familiar with the Church encoding of booleans, this post doesn’t add much, especially if you’ve seen them in Scala. This and the next post on type-level Peano numbers are intended for those unfamiliar with type-level programming. See also: The basic types involved are: We can add conditional expressions by defining a type member If on Bool. Our enhanced Bool looks like: True and False simply return the appropriate argument: Example usage: We can define some extra types in a Bool module: We can also add a method to the Bool module to convert a Bool type to a Boolean value for direct printing: For example: This is another method of checking the result of type-level computations. Next up is type-level Peano numbers.

Like this: Level Programming in Scala, Part 4c: General recursion on Peano numbers « Apocalisp. A core operation that we can use to define arithmetic operations is a fold on the list of integers from N down to _1 (so _0 is treated like an empty list). Using fold right and fold left, we can define operations like addition and multiplication. We add a FoldR type declaration to Nat as follows: where Fold is defined for types Elem and Value and provides a type function from subtypes of Elem and Value to Value.

Compare this with the type of the function that we pass to List.foldRight (represented here as a trait): We map a value of type Elem from the data structure and an accumulated value of type Value to a new accumulated value of type Value. So again, from our definition of FoldR: we see that we accept an initial type Init and that it and all future accumulations will be subtypes of Type. As mentioned previously, we can bound our type declaration by one of the type parameters, but the bound cannot change as we recurse. The implementation for _0 is easy.

We can verify that this works: Level Programming in Scala, Part 4d: Peano arithmetic « Apocalisp. Now we will use Nat#FoldR to define arithmetic on type-level natural numbers. Our type level functions and folds will follow the form of these value level functions. (In most cases, we are really just applying a function n times and not doing anything with the current iteration value.)

For reference, the Fold type was defined as: Addition looks like: Multiplication is defined in terms of addition: Factorial is defined in terms of multiplication. For whatever reason, it only worked with a fold left: Exponentiation is also in terms of multiplication: Mod uses Compare#eq: We can define: similar to toBoolean. Some examples: Operations on Nat are simple to implement using our folds, but don’t work well for reasonably large numbers or more complicated expressions. Like this: Like Loading... Level Programming in Scala, Part 4a: Peano number basics « Apocalisp. As mentioned in the opening post, we can do recursion at the type-level in Scala. The first application for this will be representing numbers in the type system (Peano numbers). One use of these is type-safe indexing into HLists, which we will do in a later post. The basic idea is not new, of course, but we are still building up the tools we need for later posts. See also: A basic representation of non-negative integers at the type level looks like: We can construct larger integers with Succ: Like for Bool, we add some structure to Nat.

The operation required for indexing into HLists is similar to the If we defined on Bool. It is similar to our Bool#If except that we accept a type constructor for the case when the Nat is Succ. We can see that this allows us to deconstruct a Nat. If A is _0, True will be the result of A#Match. Like this: Like Loading... Level Programming in Scala, Part 4b: Comparing Peano numbers « Apocalisp.

Collections