1

This code prints "Hello 1". parseInput have two generic types, the first arg is a simple object of the first generic type A, the second arg is a function which suppose to change the generic type A to generic B. As you can see it works fine in the following.

fun toGreeting(input : Int) : String {
    return "hello " + input
}

fun <A, B> parseInput(raw : A, toB : (raw : A) -> B) : B {
    return toB(raw)
}

fun main(args: Array<String>) {
    val greeting = parseInput(1, ::toGreeting)
    println(greeting)
}

The question is how can I give a default lambda value for the second named argument in the parseInput. So I can call this function by just providing the first argument, and having it to use the default lambda function.

val greeting = parseInput(1)
println(greeting)
7
  • What do you want to specify as the default value? The default value can only be a function from Any to Any, and there are not too many useful functions which fit this signature. Commented Mar 20, 2018 at 18:01
  • 1
    It seems like you can't even have an (Any) -> Any function as the default here. Since there's generics involved, a generic (A) -> B function is required, which then forces the caller to specify the generic types, as there's no way to infer B. As for the implementation of this default function, you can either cast something to B inside it (which probably won't succeed), or have it return Nothing (which is not what you want here). Commented Mar 20, 2018 at 18:06
  • @yole, a void, Unit would be good for default value. Commented Mar 20, 2018 at 18:28
  • 1
    So you want greeting in your second example to be equal to Unit? How is that useful? Commented Mar 20, 2018 at 18:31
  • @yole, right it's not useful, but I wanted it to be not useful if it isn't provided when calling the function. My goal is to make the second function optional, which is why I want a default lambda function to return Unit Commented Mar 20, 2018 at 18:34

1 Answer 1

1

Your requirements are contradictory. You want to be able to specify a function that returns a value of type B for any B (which is actually impossible by itself; the only possible such function is a function that always throws an exception), and you also want the compiler to be able to infer what B is when you haven't given the compiler any information from which it can be determined. In your example:

 val greeting = parseInput(1)  
 println(greeting)

...there is zero information from which the compiler could determine what type the greeting variable needs to have. There is no logic that would substitute Unit or any other specific type in this case; instead, as you correctly remark in your comment, this code fails to compile.

If you want greeting to be Unit in this case, you can achieve this by simply overloading the function:

fun <A> parseInput(raw: A) {
}

This function will return Unit, giving you the exact behavior you're looking for.

Sign up to request clarification or add additional context in comments.

5 Comments

Overloading would work, but it is not what I am looking for. If I have some other logics need to be processed in this parseInput? I will have to duplicate them in the overloading functions. I could move the common logics into another function which can be called in the overloading functions parseInput, but that's not what I would like to do either.
parseInput(1, ::toGreeting) works because toGreeting is providing the type to be returned. You are right that parseInput(1) fails because there is no type provided to the compiler to infer what B is. So this points back to the question, is there a way to provide a default function like toGreeting in the function signature?
There is no way to specify a default function in such a way that the compiler would take the type arguments from that default function.
It would be nice if there is a way to do so!
Just chiming in here that being able to do fun <A, B> parseInput(raw : A, toB : (raw : A) -> B = { it }) : B {} would be great, in which case it would be clear that B is the same type as A.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.