1

I have a simple code

private def convertFieldsNames (fieldsNames: Array[String]): Array[String] =
  fieldsNames.map(convertFieldName)

private def convertFieldName (fieldName: String): String = s"!!! $fieldName"

val res = convertFieldsNames(Array("123", "456"))
res.map(println)

it works fine, but when i add type conversions functions, which i'm gonna use in other functions

implicit def fromStringToEitherStringOrArray (str: String): Either[String, Array[String]] = Left(str)
implicit def fromArrayToEitherStringOrArray (arr: Array[String]): Either[String, Array[String]] = Right(arr)

i get an error in a line

fieldsNames.map(convertFieldName)

type mismatch;
 found   : String => String
 required: Array[String] => ?

i expected that these conversions will effect only if conversion to Either value is needed, so i cant get why this error bubbles up in a line where no Either type at all

0

1 Answer 1

5

Just too many implicit conversions. Try

private def convertFieldsNames (fieldsNames: Array[String]): Array[String] =
  (fieldsNames: ArrayOps[String]).map(convertFieldName)

Compiler chose wrong conversion Array[String] => Either[String, Array[String]] rather than Array[String] => ArrayOps[String] because .map can be not only Array#map but also Either#map. And type inference/type checking works so that when there is type mismatch error it's too late to come back and choose proper implicit conversion.

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

5 Comments

Can also be solved by not adding this new implicit for two very common base types (Array and String). If you don't scope that carefully, it will break other things all over the place. Why not just have an explicit function call to convert it (or just call Left or Right directly)?
Ok, i got, so any methods which belongs both to arrays and to Either types will be confused if not using ArrayOps, correct?
@Thilo, yes, i can do it, i just wanted to minimize code...And actuially i'm new to scala and just learn what can be done and what not...Another option is make sealed trait with case classes instead of Either...so i just surprised why is such behavour, but now i got - seems that map function is confusing about who called it
@DmitryReutov Conversion implicit def fromArrayToEitherStringOrArray[T] (arr: Array[T]): Either[String, Array[T]] = Right(arr) seems not to create confusion in this place.
@DmytroMitin but it does

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.