Duck typing is often used in dynamic languages - http://en.wikipedia.org/wiki/Duck_typing. You can do this with scala in a perfectly type safe way using structural types.

You can either define the signature in the method signature (as shown in the manual), but a better way for more complex structures is to use a type alias:

object structurals {
  type YourType = { def method():Something; def another():Something }
  //you can have more type aliases here if needed
}

You then import it into any scope that needs these types:

import structurals._

Then you use it like so :

  def yourMethod(f: YourType) = println(f.method())

Now you can pass around any objects that match the structural type, yet your structural definitions are nicely reusable.

Structural type extending another

Is it possible to define one structural type as extending another?

You can do this,

// untested, for scala 2.8? 31/10/2009
type Graph = { 
  def containsVertex(vertex: Int): Boolean 
  def addVertex(vertex: Int) 
  def containsEdge(source: Int, sink: Int): Boolean 
  def addEdge(source: Int, sink: Int): Any 
} 
 
type WeightedGraph = { 
  def setEdgeWeight(edge: Any, weight: Double) 
} 
 
type CombinedGraph = Graph with WeightedGraph

or

// untested, for scala 2.8? 31/10/2009
type Graph = { def containsEdge:Boolean /* etc. */ }
type WeightedGraph = Graph { def setEdgeWeight(edge:Any,weight:Double) }

No Recursive Types

I would like to declare an abstract type T that must have a method with signature join(other: T): T

Martin Odersky Jan 5, 2008: “It’s not possible. Scala has structural types, but not recursive types. Every form of recursion must go through a class or a trait. The reason is that typechecking with recursive types and Scala’s path-dependent types amounts to deciding the equality of context-free trees, which is undecidable.”

 
patterns/duck-typing-done-right.txt · Last modified: 2010/02/11 09:10
 
Recent changes RSS feed Valid XHTML 1.0 Driven by DokuWiki