0

I know that question sounds really stupid, but I'm new to scala and I cant get a function to work when I give it my custom class as an input.

class B(x:Int) {
}

@main def foo(b: B): Unit = {
  b
}

It doesn't compile and it just gives the error

"no implicit argument of type scala.util.CommandLineParser.FromString[basics.B] was found for parameter fs of method parseArgument in object CommandLineParser @main def foo(b:B):B = {

I tried using a clean file, but that didn't work either.

4
  • 2
    Just don't make it the main Commented Apr 27, 2023 at 17:58
  • thanks, it does work that way, could you explain why I don't need the @main here? Commented Apr 27, 2023 at 18:03
  • 1
    Well, because that function is not your main? Commented Apr 27, 2023 at 18:25
  • def main on JVM accepts ONLY Array[String] and this is what will be generated by @main annotation. If you want to use some custom format then use something like Scopt or Droste or Mainargs to parse your input into the class inside main. The only exception that I know of are Ammonite scripts with their own @main annotation. But that's non-standard. Commented Apr 28, 2023 at 11:24

1 Answer 1

1

As far as I know in JVM languages, of which Scala is one, the entry point to a program is called a main function, and has to follow a specific definition: it must be called main, be a static function, public, void-returning, and accept only the language's equivalent of a String[] as arguments.

In Scala 3, there is some syntax sugar offered to make the program entry point easier to define, less verbose, and more flexible. Essentially, just about any method defined at the top-level or inside of an object can be annotated with @main and become an entry point. However, what is tripping you up in this case is the argument of type B you have defined for your @main-annotated method foo(). The JVM passes arguments to your program in the form of a String array (hence why the main method must accept a String[]).

In Scala 3, if you define arguments to a @main method, the compiler will attempt to translate the string arguments passed to your program into the argument types of your main method. It does this by using given instances (previously implicits) of scala.util.CommandLineParser.FromString for the types your method expects. By default, the compiler provides instances for certain types (for example, the primitives). However, because you don't define a given instance of CommandLineParser.FromString for a B, you get the error message no implicit argument of type scala.util.CommandLineParser.FromString[basics.B] was found ...

Instead, you can make a different @main function to run your program that accepts either no args or the standard Array[String], accept in Int into your @main function and construct the B you want with that, or provide a given CommandLineParser.FromString[B], perhaps by using any of the libraries suggested in the comments.

More details: https://docs.scala-lang.org/scala3/book/methods-main-methods.html

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

Comments

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.