Pass function from Scala.js to Javascript function? - scala.js

I've defined function in Scala.js like this:
val myFunction: js.Function1[js.Array[String], Boolean] = (data: js.Array[String]) => true
And also defined Javascript function on the page:
function callFunction(inputFunction){
console.log(inputFunction(["10"]))
}
When I make a call from Scala.js:
GlobalScope.callFunction(myFunction)
I got error:
Uncaught TypeError: inputFunction is not a function
What I'm doing wrong and how to fix it?
Definition of the GlobalScope:
#JSGlobalScope
#js.native
object GlobalScope extends js.Any {
def GlobalScope.callFunction(someFunction: (js.Array[String]) => Boolean): Unit = js.native
}

The definition of callFunction in GlobalScope is erroneous. It asks for a js.Array[String] => Boolean, which is a Scala function from js.Array[String] to Boolean, not a JavaScript function. When you call it, even if you give it a js.Function1[js.Array[String], Boolean] (which is correct), the Scala type system will insert an implicit conversion from js.Function1 to scala.Function1 to conform to the expected type. But then of course the JavaScript code in callFunction receives a Scala function and is not happy with it.
The solution is to fix the definition of callFunction to take a js.Function1:
#JSGlobalScope
#js.native
object GlobalScope extends js.Any {
def callFunction(someFunction: js.Function1[js.Array[String], Boolean]): Unit = js.native
}

Related

Scala: Implicit conversion of a function doesn't work

I have this trait with a single method of type WSResponse => HTTPCallResult[A]
trait Parsable[A] {
def parse(response: WSResponse): HTTPCallResult[A]
}
I want to define an implicit conversion from a function WSResponse => A
object Parsable {
implicit class DefaultResponseParser[A](parser: WSResponse => A) extends Parsable[A] {
override def parse(r: WSResponse): HTTPCallResult[A] = {
//implementation
}
}
}
The desired behaviour is such, that if a function WSResponse => HTTPCallResult[A] is passed the anonymous class of Parsable[A] is automatically created. If a function of any other return type is passed (WSResponse => A) the implicit conversion is triggered.
However, an error occurs when compiling with SBT
[error] /Auth.scala:24:60: type mismatch;
[error] found : String
[error] required: HTTPCall.HTTPCallResult[?]
[error] (which expands to) scala.util.Either[String,?]
[error] .post((r: WSResponse) => (r.json \ "key").as[String])
This function was used in order to test it.
def post[A](parser: Parsable[A])
.post((r: WSResponse) => (r.json \ "key").as[String])
EDIT 1:
Even making the implicit class an implicit method and moving it to the very same scope as post didn't help.
EDIT 2:
It seems that the problem stems from the use of trait with single undefined method. Therefore when passed a function to the post method, the compiler tries to create an anonymous class of type Parser[A] from that. Due to a type missmatch it throws, without even trying to be looking for any implicits.

Scala ClassTag & classOf and type parameter. Strange case of generics

Here is my code straight & simple:
package scalaproj
import scala.reflect._
case class MyClass() {}
def bar[T](cls : Class[T]) = println(cls)
def foobar[T: ClassTag] = println(classTag[T])
bar(classOf[MyClass])
foobar[MyClass]
Results: class scalaproj.GetFields$MyClass$2
scalaproj.GetFields$MyClass$2
Now I would like to do the following without the famous error: "class type required but T found"
def foo[T] = println(classOf[T])
foo[MyClass]
foo is just a function that takes a Generic Type Parameter and does not need a value parameter. I think this is strange given the two examples that work and all the flexibility build in into the Scala language and its handeling of generics.
Update:
Just to specify further strangeness:
def foo1[T](t : T) = {} // no compile error
def foo2[T](): List[T] = { List[T]() } // no compile error
def foo3[T](): T = { T() } // compile error: "not found: value T"
A good explanation is appreciated.
You can't, as classOf will not work with arbitrary types (and your T is an arbitrary type).
For example:
scala> classOf[Int with String]
<console>:15: error: class type required but Int with String found
classOf[Int with String]
^
You can achieve the same thing with ClassTag#runtimeClass:
def foo[T: ClassTag] = println(classTag[T].runtimeClass)

Scala mock function with implicit generic types

I'm trying to mock Cassandra ScalaGettableData object using scalamock. I need to mock the following method:
def getMap[K : TypeConverter, V : TypeConverter](name: String) = get[Map[K, V]](name)
TypeConverter is a Trait and has implicit implementations such as:
implicit object StringConverter extends TypeConverter[String]
In my code I'm calling
scalaGettableData.getMap[String, String]("myMap")
and I guess it's implicitly converted to
scalaGettableData.getMap[StringConverter, StringConverter]("myMap")
My Test code is as following :
val cassandraRow1 = mock[ScalaGettableData]
(cassandraRow1.getMap[String, String] _).expects("localizations_config").returning(Map("key1" -> "value1"))`
But I'm getting compilation error:
Error:(28, 26) _ must follow method; cannot follow (name: String)(implicit evidence$3: com.datastax.spark.connector.types.TypeConverter[String], implicit evidence$4: com.datastax.spark.connector.types.TypeConverter[String])Map[String,String] <and> (index: Int)(implicit evidence$3: com.datastax.spark.connector.types.TypeConverter[String], implicit evidence$4: com.datastax.spark.connector.types.TypeConverter[String])Map[String,String]
How am I supposed to mock this method ?
Maybe this example helps:
"implicit parameters" should "be mockable" in {
trait Bar[T]
trait Foo {
def getMap[K : Bar](name: String): Int
}
val m = mock[Foo]
(m.getMap[Long](_: String)(_: Bar[Long])) expects(*, *) returning 42 once()
implicit val b = new Bar[Long] {}
m.getMap("bar")
}
Effectively, the type parameter K : Bar gets converted by the Scala compiler to a second parameter list, which is mocked out explicitely in this example with (_: Bar[Long]).

How to interpret this def that uses a PartialFunction?

I am still getting used to the concept of PartialFunction in Scala.
I came across the following statement that I can't wrap my head around:
Update:
def msgsToGet: PartialFunction[Any, Unit]
is defined in a trait as follows:
trait MyActorTrait {
palindrome: String => def msgsToGet: PartialFunction[Any, Unit]
//After the answers I received, I understand that the "def msgsToGet: //PartialFunction[Any, Unit]" represents the LHS of an abstract (as yet) //unimplemented function (no function body yet)
}
Now, what does that mean?
I understand that 'def' denotes a function. In this case, it is a function by name msgsToGet.
Then there is a colon (:). Okay, until now, I had always thought "after a colon, is the type, and this is where I am lost.
Okay, is it the same thing as:
def msgsToGet(): PartialFunction[Any, Unit]
[A function that takes in no parameters and returns something of type PartialFunction[Any, Unit].
PartialFunction[Any, Unit] to me somehow looks to me like a return type. But there is no function body. So what is going on here, please?
is this a syntactic sugar for something longer, but readable?
Help me interpret this, please..
If there's no function body, then it's an abstract method. Is it on a trait or an abstract class? An abstract method, like in Java, says that implementing classes must define the method.
You are correct in your analysis: it is a function called "msgsToGet" that takes no parameters and returns an object of type PartialFunction[Any, Unit].
Here's an example:
trait SomeTrait {
def msgsToGet: PartialFunction[Any, Unit]
}
class SomeClass extends SomeTrait {
def msgsToGet: PartialFunction[Any, Unit] = {
case x => println(x)
} // a case block is a partial function, so we can return this block from the function
}
val c = new SomeClass
val f = c.msgsToGet // takes no parameters, returns a partial function
f("hey") // we can call the partial function, which takes an Any parameter
// prints "hey"
It is almost the same than
def msgsToGet(): PartialFunction[Any, Unit]
Scala allows methods without a parameter list (as opposed to one empty parameter list).
In bytecode, these two are the same, but in idiomatic Scala, no parameter list is preferred for methods that are side effect free and especially accessors. Empty parameter list is preferred, ifbthe method is side effecting.

Scala Implicit function within a function call

I've defined a class that has a method in it that is trying to make use of a function with an implicit parameter in it. Unfortunately it's failing to compile
class Test {
def useImplicit(implicit a: Boolean) = a
def getAnswer() = if (useImplicit) println("yes") else println("no")
}
object Preferences {
implicit val yes = false
implicit val no = false
}
The problem is that when I go to compile the class to try and test it out I get the error
could not find implicit value for parameter a: Boolean
def getAnswer() = if (useImplicit) println("yes") else println("no")
I'm not exactly sure what is going on here. The reason for me trying it this way is I am ultimately wanting to overload hashCode and determine at runtime whether I should run my overloaded version or call the parent implementation. If this isn't possible I suppose I could make the class take an implicit
getAnswer is calling useImplicit, but there is no implicit Boolean within the scope of Test. getAnswer will also require the implicit parameter to work:
def getAnswer(implicit a: Boolean) = if(useImplicit) println("yes") else println("no")
The alternative is making Test require the implicit on instantiation, as you say.