type mismatch; found : String required: Int - string

I wrote a program which processes a string using functional programming style. It gives an odd "type mismatch;
found : String
required: Int" error on this line else if(c==('s')) helper1(s(str), s.drop(1)). Thanks in advance.
def stringpipeline(string:String) : (String) => String = {
def r(s:String):String = {s.reverse}
def s(s:String) = {s.sorted}
def U(s:String) = {s.toUpperCase}
def l(s:String) = {s.toLowerCase}
def star(s:String):String = {s.trim}
def T(s:String):String = {s.split(' ').map(_.capitalize).mkString(" ")}
def helper1(str:String, s:String): String = {
if (s.length != 0)
{
val c = s(0)
if(c==('T')) helper1(T(str), s.drop(1))
if(c==('s')) helper1(s(str), s.drop(1))
if(c==('*')) helper1(star(str),s.drop(1))
else str
}
else str
}
def helper2(strn:String): String = {helper1(strn,string)}
helper2 _
}

helper1(s(str), s.drop(1))
In code s(str) you're calling String.apply(Int) method. str is String, so compiler notifies about it

The problem is that you have declared s in two different scopes. In the overall scope you have declared s as a method which acts on a String and returns a String. In the scope of helper1() you have also declared s as a String parameter. This declaration overrides (shadows) the declaration of the method s outside helper1().
Where the error is reported, you are trying to use the method s(str), but the compiler is picking up the declaration s:String. You should fix this by renaming the name of either the method or the parameter. In general I would suggest avoiding single character names for methods, parameters or variables and instead using longer and more descriptive names - this is not a requirement to fix this problem, but you would have been more likely to avoid it by using, for example, sorted().

Related

Why a type method that should return a string returns a 'unit -> string' instead and how to solve it?

So I have this simple code, I'm trying to figure out classes and inheritance in F#:
type Mkp() =
abstract tX : unit -> string
default this.tX() = ""
type A(n : string, v : string) =
inherit Mkp()
member this.n = n
member this.v = v
override this.tX() = sprintf "%s = \"%s\" " this.n this.v
let test = A "first" "second"
let xxx = "" + test.tX
I get the compiler error: The type 'string' does not match the type 'unit -> string' but I expected test.tX to be a string, what am I doing wrong?
Your class definitions are correct, but there are two small issues when you use them:
When creating the instance, you need to pass parameters to the constructor as a tuple
i.e. you need to say A("one", "two") rather than A "one" "two"
When invoking a method, you need to specify empty parameter list i.e. test.tX()
The correct use of your class A looks like this:
let test = A("first", "second")
let xxx = "" + test.tX()

Groovy: Constructor hash collision

I have the following groovy code:
def script
String credentials_id
String repository_path
String relative_directory
String repository_url
CredentialsWrapper(script, credentials_id, repository_name, repository_group, relative_directory=null) {
this(script, credentials_id, 'git#gitlab.foo.com:' + repository_group +'/' + repository_name + '.git', relative_directory);
}
CredentialsWrapper(script, credentials_id, repository_url, relative_directory=null) {
this.script = script;
this.credentials_id = credentials_id;
this.repository_url = repository_url;
if (null == relative_directory) {
int lastSeparatorIndex = repository_url.lastIndexOf("/");
int indexOfExt = repository_url.indexOf(".git");
this.relative_directory = repository_url.substring(lastSeparatorIndex+1, indexOfExt);
}
}
Jenkins gives me the following:
Unable to compile class com.foo.CredentialsWrapper due to hash collision in constructors # line 30, column 7.
I do not understand why, the constructors are different, they do not have the same number of arguments.
Also, "script" is an instance from "WorkflowScript", but I do not know what I should import to access this class, which would allow me to declare script explicitly instead of using "def"
Any idea ?
When you call the Constructor with four parameters, would you like to call the first or the second one?
If you write an constructor/method with default values, groovy will actually generate two or more versions.
So
Test(String x, String y ="test")
will result in
Test(String x, String y) {...}
and
Test(String x) {new Test(x, "test")}
So your code would like to compile to 4 constructors, but it contains the constructor with the signature
CredentialsWrapper(def, def, def, def)
two times.
If I understand your code correctly, you can omit one or both of the =null. The result will be the same, but you will get only two or three signatures. Then you can choose between both versions by calling calling them with the right parameter count.

Expression of Type Scala.Predef.String doesn't conform to expected type String

I have a function, validateCell, that takes a function, func, as one of its input parameters. It is as follows:
def validateCell[String](cellKey: String, cell: Option[String], func:(String) => Boolean): Tuple2[Boolean, String] = {
cell match {
case Some(cellContents) => (func(cellContents), s"$cellContents is not valid.")
case None => (false, s"$cellKey, not found.")
}
}
I call the function as follows:
val map = Map("Well" -> "A110")
validateCell("Well", map.get("Well"), BarcodeWell.isValidWell)
The function that is passed in this case is as follows, though I don't think it's related to the problem:
def isValidWell(w: String): Boolean = {
val row: String = w.replaceAll("[^A-Za-z]", "")
val col: Int = w.replaceAll("[^0-9]+", "").toInt
isValidRow(row) && isValidColumn(col)
}
I am expecting validateCell to return a Tuple(Boolean, String), but I get the following error:
Error:(5, 55) type mismatch;
found : java.lang.String
required: String(in method validateCell)
case Some(cellContents) => (func(cellContents), s"$cellContents is not valid.")
I can make this error go away by converting the java strings in each tuple that are returned by the case statements to Scala strings like so:
s"$cellContents is not valid.".asInstanceOf[String]
s"$cellKey, not found.".asInstanceOf[String]
This seems really silly. What am I missing here? Shouldn't this conversion be handled by Scala automatically and why are my strings being cast as Java strings in the first place?
There is no difference between Scala strings and Java strings. In fact, Predef.String aliases to java.lang.String. However, you're working with neither of these things; you're working with a type parameter.
def validateCell[String](cellKey: String, cell: Option[String], func:(String) => Boolean): Tuple2[Boolean, String] = {
This is a generic function which takes a type argument whose name is String. When you call validateCell, this type argument is being inferred and filled in for you, by something that definitely isn't a string. My guess is that you're misunderstanding the point of the brackets and that you meant to write
def validateCell(cellKey: String, cell: Option[String], func:(String) => Boolean): Tuple2[Boolean, String] = {

String literal not interpreted as type String

I'm trying to implement a simple subclass of Iterable[String], and I'm encountering something that seems a bit strange to me. My code is as follows:
class ItString[String] extends Iterable[String]{
override def iterator: Iterator[String] = new Iterator[String] {
def hasNext = true
def next = "/"
}
}
My IDE complains that it's expecting a String but it's actually of type String, and when trying to compile, it further reveals that the problem is that it requires String but that the literal is actually of type java.lang.String. Now, I can fix this by changing it to "/".asInstanceOf[String], but I'd like to know why Scala isn't recognising the type correctly.
Since I can get the following to compile:
class ItString extends Iterable[String] {
override def iterator: Iterator[String] = new Iterator[String] {
def hasNext = true
def next = "/"
}
}
I can deduce that your problem is with writing:
class ItString[String] extends ...
What's going on is that this occurrence of String doesn't refer to the type java.lang.String, but it is instead an unknown parameterised type (like T or A). So, when you write [String], this means some unknown type that will be determined by the implementing class rather than the String type that you intended.

how can i append to each line in scala and why is it saying unit?

im doing something stupid to try to send html email and not really understanding what im doing but I want to send a multiline string to a function and get the same string back with something appended to each line - what am i doing wrong?
def htmlizetext(intext: String) {
for(line <- intext.linesWithSeparators) {
<br>line<br/>
}
}
def htmlizetext(intext: String): String = {
for(line <- intext.linesWithSeparators) {
line + "<br/>"
}
}
Neither of the above work
You need yield, = (without = the method will still return Unit) and some form of concatenation:
def htmlizetext(intext: String) = {
for (line <- intext.linesWithSeparators) yield {
line + "<br/>
}
}.mkString
or the shorter equivalent:
def htmlizetext(intext: String) =
intext.linesWithSeparators.map(_ + "<br/>").mkString
Have a look at yield, that is probably what you are looking for.
def htmlizetext(intext: String) = {
for(line <- intext.linesWithSeparators) yield {
<br>line<br/>
}
}
You might additionally want to join all the elements from the returning list for returning a single String instead of a list of such strings
You are currently not returning a thing from your method as you do not return anything from your for statement which is the last method of your statement. Therefore, the Scala compiler infers that you are returning Unit.
Because for does't have a return value, unless you use yield...
A better solution would be to "map" your collection as follows:
intext.linesWithSeparators.map(line=> s"$line<br/>").mkString("")
this will turn your string in the desired format and then join all of them using mkString. If you need it, you can specify a separator instead of empty string

Resources