Type parameterization in Scala - templates

So I'm learning Scala at the moment, and I'm trying to create an abstract vector class with a vector-space of 3 (x,y,z coordinates). I'm trying to add two of these vectors together with the following code:
package math
class Vector3[T](ax:T,ay:T,az:T) {
def x = ax
def y = ay
def z = az
override def toString = "&lt"+x+", "+y+", "+z+"&gt"
def add(that: Vector3[T]) = new Vector3(x+that.x, y+that.y, z+that.z)
}
The problem is I keep getting this error:
error: type mismatch; found :
T required: String def
add(that: Vector3[T]) = new
Vector3(x+that.x, y+that.y,
z+that.z)
I've tried commenting out the "toString" method above, but that doesn't seem to have any effect. Can anyone tell me what I'm doing wrong?

Using Scala 2.8, you could write:
case class Vector3[T: Numeric](val x: T, val y: T, val z: T) {
override def toString = "(%s, %s, %s)" format (x, y, z)
def add(that: Vector3[T]) = new Vector3(
plus(x, that.x),
plus(y, that.y),
plus(z, that.z)
)
private def plus(x: T, y: T) = implicitly[Numeric[T]] plus (x, y)
}
Let me explain. First, T: Numeric is a context bound that implicitly provides a Numeric[T] instance to your class.
The Numeric[T] trait provides operations on numeric types,
trait Numeric[T] extends Ordering[T] {
def plus(x: T, y: T): T
def minus(x: T, y: T): T
def times(x: T, y: T): T
def negate(x: T): T
// other operations omitted
}
The expression implicitly[Numeric[T]] retrieves this implicit context such that you can perform the operations such as plus on your concrete arguments x, y and z, as illustrated in the private method above.
You can now construct and add different instantiations of Vector3 such as with Int's and Double's:
scala> Vector3(1,2,3) add Vector3(4,5,6)
res1: Vector3[Int] = (5, 7, 9)
scala> Vector3(1.1, 2.2, 3.3) add Vector3(4.4, 5.5, 6.6)
res2: Vector3[Double] = (5.5, 7.7, 9.899999999999999)
Side-note: It's possible to use implicit conversions to convert values to Numeric[T].Ops instances such that the following could be written instead:
def add(that: Vector3[T]) = new Vector3(x + that.x, y + that.y, z + that.z)
I've deliberately chosen not to use these implicit conversions since they (may) incur some performance penalty by creating temporary wrapper objects. Actual performance impact depends on the JVM (e.g., to which extent its supports escape analysis to avoid actual object allocation on heap). Using a context bound and implicitly avoids this potential overhead ... at the cost of some verbosity.

You have not constrained the type parameter T and so the compiler is falling back to the interpretation of + as String concatenation.

The problem is T. It's of type Any, but Any doesn't have a + operator. The error about String is a bit miss leading. So you're going to have to define the min bound to a type that does.

Both the answers from #sblundy and #Randall Schulz are correct, of course, but in case you need some more concrete advice about how to constrain T then how about:
class Vector3[T <% Double](ax:T,ay:T,az:T) {
...
}

Related

How to pass method to block in Crystal

How to pass plus into calculate method?
def calculate(&block : (Float64, Float64) -> Float64)
block.call(1.1, 2.2)
end
def plus(a, b)
a + b
end
calculate{|a, b| plus a, b}
This won't work
calculate ->plus
calculate &plus
P.S.
Another question, how to make it to work for all numbers? Not just Float64. This code won't compile and complain about requiring more specific type than Number
def calculate(&block : (Number, Number) -> Number)
block.call(1, 2)
end
Ideally it would be nice to make it generalised so that typeof(block.call(1, 2)) => Int32 and typeof(block.call(1.1, 2.2)) => Float64
How to pass plus into calculate method?
You're looking for
calculate(&->plus(Float64, Float64))
Where ->plus(Float64, Float64) returns a Proc. Mind that you have to specify the type of the arguments - see the section From methods in the reference manual.
how to make it to work for all numbers?
I'd look into forall - see the section on Free variables in the reference manual.
A generalized solution could work with free variables, but there's a catch because free variables can't be derived from block arguments:
def calculate(&block : (T, T) -> T) forall T # Error: undefined constant T
This is because block arguments can't be overloaded since they can simply be captured blocks without type restrictions.
There are two options to make this work:
You can pass the type for T explicitly as an argument. This is a bit more verbose but works with a captured block argument.
def plus(a, b)
a + b
end
def calculate(t : T.class, &block : (T, T) -> T) forall T
block.call(1.1, 2.2)
end
calculate(Float64, &->plus(Float64, Float64))
You can change the captured block argument to a normal argument receiving a Proc:
def plus(a, b)
a + b
end
def calculate(block : (T, T) -> T) forall T
block.call(1.1, 2.2)
end
calculate(->plus(Float64, Float64))

OCaml Signature with multiple types

I would like to represent some scalar value (e.g. integers or strings)
by either it's real value or by some NA value and later store them
in a collection (e.g. a list). The purpose is to handle missing values.
To do this, I have implemented a signature
module type Scalar = sig
type t
type v = Value of t | NA
end
Now I have some polymorphic Vector type in mind that contains Scalars. Basically, some of the following
module Make_vector(S: Scalar) = struct
type t = S.v list
... rest of the functor ...
end
However, I cannot get this to work. I would like to do something like
module Int_vector = Make_vector(
struct
type t = int
end
)
module Str_vector = Make_vector(
struct
type t = string
end
)
... and so on for some types.
I have not yet worked a lot with OCaml so maybe this is not the right way. Any advises on how to realize such a polymorphic Scalar with a sum type?
The compiler always responds with the following message:
The parameter cannot be eliminated in the result type.
Please bind the argument to a module identifier.
Before, I have tried to implement Scalar as a sum type but ran into
complexity issues when realizing some features due to huge match clauses. Another (imo not so nice) option would be to use option. Is this a better strategy?
As far as I can see, you are structuring v as an input type to your functor, but you really want it to be an output type. Then when you apply the functor, you supply only the type t but not v. My suggestion is to move the definition of v into your implementation of Make_vector.
What are you trying to do exactly with modules / functors? Why simple 'a option list is not good enough? You can have functions operating on it, e.g.
let rec count_missing ?acc:(acc=0) = function
| None::tail -> count_missing ~acc:(acc+1) tail
| _::tail -> count_missing ~acc tail
| [] -> acc ;;
val count_missing : ?acc:int -> 'a option list -> int = <fun>
count_missing [None; Some 1; None; Some 2] ;;
- : int = 2
count_missing [Some "foo"; None; Some "bar"] ;;
- : int = 1

How SML achieve abstraction? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am new in SML and it is my first time to learn a functional language. I suppose there is abstraction of SML. I have not found perfect explanation of how to achieve abstraction in SML. Does anyone can offer a explanation?
Generally speaking, there are at least two forms of "abstraction" in programming:
Abstracting the client (parameterisation)
Abstracting the implementation (encapsulation)
(If you care, these correspond to universal and existential quantification in logic and type theory.)
In ML, parameterisation can be done on two levels. Either in the small, using functions (abstraction over values) and polymorphism (abstraction over types). Note in particular that functions are first-class, so you can parameterise one function over another. For example:
fun map f [] = []
| map f (x::xs) = f x :: map f xs
abstracts list transformation over the transforming function f as well as the element types.
In the large, parameterisation can be done using the module system: a functor abstracts a whole module over another module (i.e., over both values and types). For example, you could also write the map function as a functor:
functor Mapper(type t; type u; val f : t -> u) =
struct
fun map [] = []
| map (x::xs) = f x :: map xs
end
But usually you use functors for mass abstraction, i.e., in cases where there is more than just a single function you need to parameterise.
Encapsulation is also achieved by using modules. Specifically, by sealing them, i.e., hiding details of their types behind a signature. For example, here is a (naive) implementation of integer sets:
signature INT_SET =
sig
type set
val empty : set
val add : int * set -> set
val mem : int * set -> bool
end
structure IntSet :> INT_SET = (* ':>' hides the implementation of type set *)
struct
type set = int list
val empty = []
fun add(x, s) = x::s
fun mem(x, s) = List.exists (fn y => y = x) s
end
Outside the structure IntSet, its type set is fully abstract, i.e., it cannot be interchanged with lists. That is the purpose of the so-called sealing operator :> for modules.
Both forms of abstraction can occur together. For example, in ML one would usually implement a set as a functor:
signature ORD =
sig
type t
val compare : t * t -> order
end
signature SET =
sig
type elem
type set
val empty : set
val add : elem * set -> set
val mem : elem * set -> bool
end
functor Set(Elem : ORD) :> SET where type elem = Elem.t =
struct
type elem = Elem.t
datatype set = Empty | Branch of set * elem * set
val empty = Empty
fun add(x, Empty) = Branch(Empty, x, Empty)
| add(x, Branch(l, y, r)) =
case Elem.compare(x, y) of
LESS => Branch(add(x, l), y, r)
| EQUAL => Branch(l, y, r)
| GREATER => Branch(l, y, add(x, r))
fun mem(x, Empty) = false
| mem(x, Branch(l, y, r)) =
case Elem.compare(x, y) of
LESS => mem(x, l)
| EQUAL => true
| GREATER => mem(x, r)
end
This implementation of sets works for any type for which an ordering function can be provided. Unlike the naive implementation before, it also uses a more efficient search tree as its implementation. However, that is not observable outside, because the type's implementation is again hidden.
SML programs frequently are build on a descriptive types for the problem at hand. The language then uses pattern matching to figure out what case your are working with.
datatype Shape = Circle of real | Rectangle of real*real | Square of real
val a = Circle(0.2)
val b = Square(1.3)
val c = Rectangle(4.0,2.0)
fun area (Circle(r)) = 3.14 * r * r
| area (Square(s)) = s * s
| area (Rectangle(b,h)) = b * h
Does this help to explain a little about sml?
In SML you can define "abstractions" by means of using a combination of things like algebraic data types and signatures.
Algebraic data types let you define new types specific to the problem domain and signatures let you provide functionality/behavior around those types and provide a convenient way to implement information hiding and extensibility and reusability.
Combining this things you can create "abstractions" whose implementation details are hidden from you and that you simply understand through their public interfaces (whatever the signature expose).

defining a simple implicit Arbitary

I have a type Foo with a constructor that takes an Int. How do I define an implicit Arbitrary for Foo to be used with scalacheck?
implicit def arbFoo: Arbitrary[Foo] = ???
I came up with the following solution, but it's a bit too "manual" and low-level for my taste:
val fooGen = for (i <- Gen.choose(Int.MinValue, Int.MaxValue)) yield new Foo(i)
implicit def arbFoo: Arbitrary[Foo] = Arbitrary(fooGen)
Ideally, I would want a higher-order function where I just have to plug in an Int => Foo function.
I managed to cut it down to:
implicit def arbFoo = Arbitrary(Gen.resultOf((i: Int) => new Foo(i)))
But I still feel like there has got to be a slightly simpler way.
Well, you can use the underscore notation instead of defining the whole Foo-creating function as (i: Int) => new Foo(i)):
class Foo(i: Int)
(1 to 3).map(new Foo(_))
This works because Scala knows that Foo takes an Int, and that map is mapping over Ints, so there's no need to spell it all out explicitly.
So this is a bit shorter:
implicit def arbFoo = Arbitrary(Gen.resultOf(new Foo(_)))

Scala: Remove duplicates in list of objects

I've got a list of objects List[Object] which are all instantiated from the same class. This class has a field which must be unique Object.property. What is the cleanest way to iterate the list of objects and remove all objects(but the first) with the same property?
list.groupBy(_.property).map(_._2.head)
Explanation: The groupBy method accepts a function that converts an element to a key for grouping. _.property is just shorthand for elem: Object => elem.property (the compiler generates a unique name, something like x$1). So now we have a map Map[Property, List[Object]]. A Map[K,V] extends Traversable[(K,V)]. So it can be traversed like a list, but elements are a tuple. This is similar to Java's Map#entrySet(). The map method creates a new collection by iterating each element and applying a function to it. In this case the function is _._2.head which is shorthand for elem: (Property, List[Object]) => elem._2.head. _2 is just a method of Tuple that returns the second element. The second element is List[Object] and head returns the first element
To get the result to be a type you want:
import collection.breakOut
val l2: List[Object] = list.groupBy(_.property).map(_._2.head)(breakOut)
To explain briefly, map actually expects two arguments, a function and an object that is used to construct the result. In the first code snippet you don't see the second value because it is marked as implicit and so provided by the compiler from a list of predefined values in scope. The result is usually obtained from the mapped container. This is usually a good thing. map on List will return List, map on Array will return Array etc. In this case however, we want to express the container we want as result. This is where the breakOut method is used. It constructs a builder (the thing that builds results) by only looking at the desired result type. It is a generic method and the compiler infers its generic types because we explicitly typed l2 to be List[Object] or, to preserve order (assuming Object#property is of type Property):
list.foldRight((List[Object](), Set[Property]())) {
case (o, cum#(objects, props)) =>
if (props(o.property)) cum else (o :: objects, props + o.property))
}._1
foldRight is a method that accepts an initial result and a function that accepts an element and returns an updated result. The method iterates each element, updating the result according to applying the function to each element and returning the final result. We go from right to left (rather than left to right with foldLeft) because we are prepending to objects - this is O(1), but appending is O(N). Also observe the good styling here, we are using a pattern match to extract the elements.
In this case, the initial result is a pair (tuple) of an empty list and a set. The list is the result we're interested in and the set is used to keep track of what properties we already encountered. In each iteration we check if the set props already contains the property (in Scala, obj(x) is translated to obj.apply(x). In Set, the method apply is def apply(a: A): Boolean. That is, accepts an element and returns true / false if it exists or not). If the property exists (already encountered), the result is returned as-is. Otherwise the result is updated to contain the object (o :: objects) and the property is recorded (props + o.property)
Update: #andreypopp wanted a generic method:
import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
class RichCollection[A, Repr](xs: IterableLike[A, Repr]){
def distinctBy[B, That](f: A => B)(implicit cbf: CanBuildFrom[Repr, A, That]) = {
val builder = cbf(xs.repr)
val i = xs.iterator
var set = Set[B]()
while (i.hasNext) {
val o = i.next
val b = f(o)
if (!set(b)) {
set += b
builder += o
}
}
builder.result
}
}
implicit def toRich[A, Repr](xs: IterableLike[A, Repr]) = new RichCollection(xs)
to use:
scala> list.distinctBy(_.property)
res7: List[Obj] = List(Obj(1), Obj(2), Obj(3))
Also note that this is pretty efficient as we are using a builder. If you have really large lists, you may want to use a mutable HashSet instead of a regular set and benchmark the performance.
Starting Scala 2.13, most collections are now provided with a distinctBy method which returns all elements of the sequence ignoring the duplicates after applying a given transforming function:
list.distinctBy(_.property)
For instance:
List(("a", 2), ("b", 2), ("a", 5)).distinctBy(_._1) // List((a,2), (b,2))
List(("a", 2.7), ("b", 2.1), ("a", 5.4)).distinctBy(_._2.floor) // List((a,2.7), (a,5.4))
Here is a little bit sneaky but fast solution that preserves order:
list.filterNot{ var set = Set[Property]()
obj => val b = set(obj.property); set += obj.property; b}
Although it uses internally a var, I think it is easier to understand and to read than the foldLeft-solution.
A lot of good answers above. However, distinctBy is already in Scala, but in a not-so-obvious place. Perhaps you can use it like
def distinctBy[A, B](xs: List[A])(f: A => B): List[A] =
scala.reflect.internal.util.Collections.distinctBy(xs)(f)
With preserve order:
def distinctBy[L, E](list: List[L])(f: L => E): List[L] =
list.foldLeft((Vector.empty[L], Set.empty[E])) {
case ((acc, set), item) =>
val key = f(item)
if (set.contains(key)) (acc, set)
else (acc :+ item, set + key)
}._1.toList
distinctBy(list)(_.property)
One more solution
#tailrec
def collectUnique(l: List[Object], s: Set[Property], u: List[Object]): List[Object] = l match {
case Nil => u.reverse
case (h :: t) =>
if (s(h.property)) collectUnique(t, s, u) else collectUnique(t, s + h.prop, h :: u)
}
I found a way to make it work with groupBy, with one intermediary step:
def distinctBy[T, P, From[X] <: TraversableLike[X, From[X]]](collection: From[T])(property: T => P): From[T] = {
val uniqueValues: Set[T] = collection.groupBy(property).map(_._2.head)(breakOut)
collection.filter(uniqueValues)
}
Use it like this:
scala> distinctBy(List(redVolvo, bluePrius, redLeon))(_.color)
res0: List[Car] = List(redVolvo, bluePrius)
Similar to IttayD's first solution, but it filters the original collection based on the set of unique values. If my expectations are correct, this does three traversals: one for groupBy, one for map and one for filter. It maintains the ordering of the original collection, but does not necessarily take the first value for each property. For example, it could have returned List(bluePrius, redLeon) instead.
Of course, IttayD's solution is still faster since it does only one traversal.
My solution also has the disadvantage that, if the collection has Cars that are actually the same, both will be in the output list. This could be fixed by removing filter and returning uniqueValues directly, with type From[T]. However, it seems like CanBuildFrom[Map[P, From[T]], T, From[T]] does not exist... suggestions are welcome!
With a collection and a function from a record to a key this yields a list of records distinct by key. It's not clear whether groupBy will preserve the order in the original collection. It may even depend on the type of collection. I'm guessing either head or last will consistently yield the earliest element.
collection.groupBy(keyFunction).values.map(_.head)
When will Scala get a nubBy? It's been in Haskell for decades.
If you want to remove duplicates and preserve the order of the list you can try this two liner:
val tmpUniqueList = scala.collection.mutable.Set[String]()
val myUniqueObjects = for(o <- myObjects if tmpUniqueList.add(o.property)) yield o
this is entirely a rip of #IttayD 's answer, but unfortunately I don't have enough reputation to comment.
Rather than creating an implicit function to convert your iteratble, you can simply create an implicit class:
import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
implicit class RichCollection[A, Repr](xs: IterableLike[A, Repr]){
def distinctBy[B, That](f: A => B)(implicit cbf: CanBuildFrom[Repr, A, That]) = {
val builder = cbf(xs.repr)
val i = xs.iterator
var set = Set[B]()
while (i.hasNext) {
val o = i.next
val b = f(o)
if (!set(b)) {
set += b
builder += o
}
}
builder.result
}
}