Coming back to Scala after a spell writing Haskell, I've started using the type keyword to make my class definitions a bit more readable, eg:
type RestfulParams = Map[String, String] def canonicalize(params: RestfulParams): String = { ... }
The trouble I've run into is that these type definitions need to live inside a class or object - they're not "first class citizens" like they are in Haskell. If I try to define a type outside of a class or object, I get a compiler expected class or object definition
.
My problem then is how to use these types across multiple classes and objects in a package? What I've done now seems quite ugly:
object RestfulTypes { type RestfulParams = Map[String, String] etc }
And then in another class file:
import utils.{RestfulTypes => RT} def get(resource: String, params: RT.RestfulParams): String = { ... }
Is there a nicer way of doing this - and incidentally do the Scala gurus think it's a good thing or a bad thing that types can only be defined inside classes/objects?
Scala is a statically typed programming language. This means the compiler determines the type of a variable at compile time. Type declaration is a Scala feature that enables us to declare our own types.
Non-value types capture properties of identifiers that are not values. For example, a type constructor does not directly specify a type of values. However, when a type constructor is applied to the correct type arguments, it yields a first-order type, which may be a value type.
Basic ClassClass variables are called, fields of the class and methods are called class methods. The class name works as a class constructor which can take a number of parameters. The above code defines two constructor arguments, xc and yc; they are both visible in the whole body of the class.
A type class is an abstract, parameterized type that lets you add new behavior to any closed data type without using sub-typing. If you are coming from Java, you can think of type classes as something like java.
Will package objects work for you?
From the article:
Until 2.8, the only things you could put in a package were classes, traits, and standalone objects. These are by far the most common definitions that are placed at the top level of a package, but Scala 2.8 doesn't limit you to just those. Any kind of definition that you can put inside a class, you can also put at the top level of a package. If you have some helper method you'd like to be in scope for an entire package, go ahead and put it right at the top level of the package. To do so, you put the definitions in a package object. Each package is allowed to have one package object. Any definitions placed in a package object are considered members of the package itself.
The package object scala has many types and values already, so I think you can use the same technique for your own types.
I'm not sure what constitutes niceness in this case, but here are two options:
Using a trait: (Scala's Selfless Trait Pattern)
trait RestfulTypes { type Params = Map[String,String] //... } object MyRestService extends RestService with RestfulTypes { /* ... */ }
Or just import the object's members, effectively using it like a package:
import util.RestfulTypes._
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With