3

I am trying to write a typed façade for my library Paths.js, following the official guide.

Following advice from Sebastien in Typed façade for JS library in Scala.js, I was able to flesh out part of the API. What I am now missing is a way to deal with a conversion function which is exposed in the API. Basically, the library lets you write something like

var pie = Pie({
  data: [
    { name: 'Italy', population: 59859996 },
    { name: 'Mexico', population: 118395054 },
    { name: 'France', population: 65806000 }
  ],
  accessor: function(x) { return x.population; },
  center: [20, 15],
  r: 30,
  R: 50
});

The idea is that - to simplify client code - the library does not require you to transform your data to a form that is amenable to plotting. Rather, you can provide a list of data in the form that you see fit, and then pass an accessor function to extract a number from the raw datum. This also makes it easier to associate path objects with the original datum.

The signature that I would like to expose on the Scala side would look like this:

object Pie {
  type Point = (Double, Double)
  def apply(data: Seq[A],
    accessor: A => Double,
    center: Point, r: Double, R: Double)
}

I am trying to convert accessor, which has type A => Double to something like js.Function1[js.Any, Double], and my attempt looks like (using the implicit conversion between Function1 and js.Function1)

val f: js.Any => Double = x => x match {
  case _: A => accessor(x)
  case _ => ???
}

This gives me a warning abstract type pattern A is unchecked since it is eliminated by erasure.

What would be a better way to translate this API?

Community
  • 1
  • 1
Andrea
  • 20,253
  • 23
  • 114
  • 183
  • Why do you want `js.Function1[js.Any, Double]`? Isn't `js.Function1[A, Double]` what you want. Then the `A => Double` would simply convert implicitly to `js.Function1[A, Double]`. – sjrd Feb 18 '15 at 12:10
  • Yes, I actually want `js.Function1[A, Double]`. But the underlying native method does not know about types. Can we have polymorphic methods declared as native? – Andrea Feb 18 '15 at 13:40
  • I have tried and I found no problem so far in defining a polymorphic trait that extends `js.Object`, having polymorphic native methods. Can this have unintended side-effects? – Andrea Feb 18 '15 at 13:59
  • No that's meant to work. It is even documented somewhere in [the doc](http://www.scala-js.org/doc/calling-javascript.html): "JS traits and their methods can have type parameters, abstract type members and type aliases, without restriction compared to Scala's type system." – sjrd Feb 18 '15 at 15:15
  • Great! I am almost done :-) – Andrea Feb 18 '15 at 15:51

1 Answers1

1

To resume the discussion in the comments:

Using a js.Function1[A, Double] is perfectly valid and reasonable in this case.

As @sjrd cites from the Scala.js doc:

JS traits and their methods can have type parameters, abstract type members and type aliases, without restriction compared to Scala's type system.

gzm0
  • 14,752
  • 1
  • 36
  • 64