Coo LHibou
Coo LHibou

Reputation: 169

How to test that an object is not a function in scala

My problem is quite simple : I want to have an implicit conversion of value to function if they are not already function. I plan to use a type safe pattern by requesting the instantiation of an implicit parameter (if the valueis a function the implicit creation fails). However I do not see how to test that a value is not a function

I learned type safe pattern from user Beryllium in one of my previous question. See : Type safe method chaining that doesn't allow repeats of operations

The implicit I've implemented is working, but too well. I want to transform not function expression to specific-application-default function automatically

 implicit def defaultExecutionUnitParameterNReturn(a: Any): Unit => MyDefaultReturn = 
{u : Unit => a }.andThen(_ => defaultReturn())

However my application would fail if the user implements "a" as a function

So my first idea was something like

 implicit def defaultExecutionUnitParameterNReturn[A](a: A)(implicit e : A =!= Function) Unit => MyDefaultReturn = 
{u : Unit => a }.andThen(_ => defaultReturn())

where implicit =!=[A,B] fails if A and B are the same type. But "Function" does not exists

Upvotes: 1

Views: 182

Answers (2)

Eric
Eric

Reputation: 15557

You need to place your implicit conversions in 2 traits

trait Implicits extends ImplicitsLow {
  implicit def convertFunction[T, R](f: T => R) = ???
}

trait ImplicitsLow {
  implicit def convert[T](t: T) = ???
}

Then you can observe that the function conversion is used in preference to the value one:

val result1: String = (i: Int) => i + 1
val result2: String = 1

// prints (function, value)   
println((result1, result2))

Upvotes: 2

pawel.panasewicz
pawel.panasewicz

Reputation: 1833

Investigate below code snipped. This is standard implicit convertion example. toFunnction0 takes anything and converts it into Function0[R] or just simplified () => R.

implicit def toFunnction0[R](r: => R): Function0[R] = () => r

def iWantFunction0(f0: () => String) = {
  f0()
}

def testFun = {println("computing string in testFun..."); "ABC"} //every time when called block of code will run
val abcVal = "ABC" //this is computed only once

iWantFunction0(testFun)

//here abcVal is not a function, so implicit works. 
//toFunnction0 is in scope, so compiler will translate it into
//iWantFunction0(toFunnction0(abcVal))  
iWantFunction0(abcVal)  

Upvotes: 0

Related Questions