Type mismatch with type alias [duplicate] - scala

This question already has answers here:
when does it need explicit type when declare variable in scala?
(3 answers)
What is a function literal in Scala?
(3 answers)
Closed 3 years ago.
I have the following code, that does not compile:
object PcpProtocol {
private type PcpHead = String
private type PcpBody = String
private type PcpValidity[A] = Either[String, A]
private val PcpIndicator = "pcp-channel:apc"
implicit val pcpProtocol: Protocol[PcpProtocol] = new Protocol[PcpProtocol] {
override def encode(text: String): PcpProtocol = ???
override def decode(msg: PcpProtocol): String = ???
}
private val validatePcp: PcpValidity[PcpHead] = (head: String) => {
if (head.contains(PcpIndicator)) {
Right(head)
} else {
Left("The message does not correspond to SAP PCP protocol")
}
}
}
The error message says:
type mismatch;
[error] found : String => scala.util.Either[String,String]
[error] required: com.sweetsoft.PcpProtocol.PcpValidity[com.sweetsoft.PcpProtocol.PcpHead]
[error] (which expands to) scala.util.Either[String,String]
[error] private val validatePcp: PcpValidity[PcpHead] = (head: String) => {
I can not figure out the error. What is wrong?

Related

could not find implicit value for param in scala

Stuck with a compilation error in my scala code
that reads implicit value could not be found . Could somebody point out what I am doing wrong?
Error :
could not find implicit value for evidence parameter of type scopt.Read[Array[String]]
opt[Array[String]](
^
one error found
My code
case class Myclass (
listC: Array[String] = Array()
)
object Myclass {
def parseArgs(args: Seq[String]): Myclass = {
val parser = new scopt.OptionParser[Myclass](
"ValidateData") {
opt[Array[String]](
"disabled.implicit.assertions") optional () action { (x, c) =>
c.copy(disabledImplicitAssertions = x)
}
}
}

How to compose two functions?

I have two functions, that I am trying to compose it:
private def convert(value: String)
: Path = decode[Path](value) match {
private def verify(parsed: Path)
: Path = parsed.os match {
I've tried as following:
verify compose convert _
The compiler complains:
[error] Unapplied methods are only converted to functions when a function type is expected.
[error] You can make this conversion explicit by writing `verify _` or `verify(_)` instead of `verify`.
[error] verify compose convert _
[error] ^
[error] one error found
I am trying to accomplish the following:
def process(value: String)
: Path =
verify(convert(value))
What am I doing wrong?
The problem is not everything in scala is a function. convert and verify in your example are methods not functions.
1) If you want to compose functions, define as functions as example below,
functions,
scala> def convert: String => String = (value: String) => "converted"
convert: String => String
scala> def verify = (value: String) => if(value == "converted") "valid" else "invalid"
verify: String => String
compose fns
scala> def vc = verify compose convert
vc: String => String
apply fn composition to functor
scala> Some("my-data").map{ vc.apply }
res29: Option[String] = Some(valid)
2) The another way is convert your existing methods to functions as below,
scala> def vc = (verify _ compose (convert _))
vc: String => String
scala> Some("data to convert").map { vc.apply }
res36: Option[String] = Some(valid)
References
https://twitter.github.io/scala_school/pattern-matching-and-functional-composition.html
Chapter 21 - Functions/Function literals
Function composition of methods, functions, and partially applied functions in Scala

Slick select using value object (extending AnyVal)

I am using Slick 2.1.0 with Scala 2.10.
I have a value object (EMail) that I map to a VARCHAR column.
object EMail {
import java.util.regex.Pattern
val emailRegex = Pattern.compile("^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE)
val empty = EMail("x#y.com")
}
case class EMail(value: String) extends AnyVal with MappedTo[String] {
def isValid: Boolean = EMail.emailRegex.matcher(value).find
def validate: EMail = {
assert(isValid)
EMail(value.trim.toLowerCase)
}
override def toString = validate.value
}
The Column definition is:
def email = column[Option[EMail]]("email_address")
This is my attempt at writing a finder:
def findByEmail(email: Option[EMail]): Option[User] =
database.withSession { implicit session: Session =>
queryAll.filter(e => e.email.isDefined && e.email === email).firstOption
}
This is the error message I get:
[error] Users.scala:52: ambiguous implicit values:
[error] both value BooleanCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[Boolean]
[error] and value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => scala.slick.lifted.CanBeQueryCondition[scala.slick.lifted.Column[Option[Boolean]]]
[error] match expected type scala.slick.lifted.CanBeQueryCondition[Nothing]
[error] queryAll.filter(_.email === email.map(_.value)).firstOption
[error] ^
You don't have to pass an Option[EMail] to your method, you could simply make:
def findByEmail(email: EMail): Option[User] = {
database.withSession { implicit session =>
queryAll.filter(_.email === email).firstOption
}
}
If you really need an Option[EMail]] as the input parameter, you should try the following:
def findByEmail(emailOpt: Option[EMail]): Option[User] = {
emailOpt.flatMap { email =>
database.withSession { implicit session =>
queryAll.filter(_.email === email).firstOption
}
}
}

error: type mismatch; found: Unit.type required: Unit

Code snippets are from the Scala REPL.
This is perfectly legal Scala even though it is not very useful:
scala> class Test {
private val xs = scala.collection.mutable.ArrayBuffer[Int]()
private val func = Some((x: Int)=>{
})
private var opt: Option[(Int)=>Unit] = None
opt = func
}
defined class Test
However, if I try to do something inside func the code will not compile:
scala> class Test {
private val xs = scala.collection.mutable.ArrayBuffer[Int]()
private val func = Some((x: Int)=>{
xs += x
})
private var opt: Option[(Int)=>Unit] = None
opt = func
}
<console>:13: error: type mismatch;
found : Some[Int => Test.this.xs.type]
required: Option[Int => Unit]
opt = func
^
Instead it produces the type mismatch error and lists the types found and required. While this error message is useful, I don't know how to fix it. My next attempt was this:
scala> class Test {
private val xs = scala.collection.mutable.ArrayBuffer[Int]()
private val func = Some((x: Int)=>{
xs += x
Unit
})
private var opt: Option[(Int)=>Unit] = None
opt = func
}
<console>:14: error: type mismatch;
found : Some[Int => Unit.type]
required: Option[Int => Unit]
opt = func
^
I understand that there is a type mismatch occurring, but I don't understand why there is a type mismatch or how to fix it in such a way that I can do something useful inside func.
Why is there a type mismatch and how can it be fixed?
Function inside options uses mutable array buffer and returns it as a result, but you need Unit, you can do it this way:
private val func = Some((x: Int)=> {xs += x; ()})
or use append which return type is Unit
private val func = Some((x: Int) => xs.append(x))

Type safe String interpolation in Scala

Inspired by this, I was wondering if we can have type-safe string interpolations in Scala (maybe using macros)?
For example, I want to have something like this
def a[A] = ???
val greetFormat = f"Hi! My name is ${a[String]}. I am ${a[Int]} years old"
greetFormat.format("Rick", 27) // compiles
//greetFormat.format("Rick", false) // does not compile
//greetFormat.format(27, "Rick") // does not compile
//greetFormat.format("Rick", 27, false) // does not compile
//greetFormat.format("Rick") // does not compile or is curried?
The f string interpolator is already implemented with a macro.
This can be demonstrated inside of the REPL:
scala> val b = "not a number"
b: String = not a number
scala> f"$b%02d"
<console>:9: error: type mismatch;
found : String
required: Int
f"$b%02d"
^
Just wrap it in a function.
def greet(name: String, age: Int) = s"Hi! My name is $name. I am $age years old"
You can supply implicits to the f-interpolator:
scala> case class A(i: Int)
defined class A
scala> implicit def atoi(a: A): Int = a.i
warning: there were 1 feature warning(s); re-run with -feature for details
atoi: (a: A)Int
scala> f"${A(42)}%02d"
res5: String = 42
See also Travis Brown's examples and solution for using regex group names in extractions. It took me about a minute to steal that great idea.
"a123bc" match {
case res # xr"(?<c>a)(?<n>\d+)(?<s>bc)" => assert {
res.c == 'a' && res.n == 123 && res.s == "bc"
}
}
For the record, on the composition side, I would like:
val a = A(Rick, 42)
val greeter = f"Hi! My name is $_. I am ${_}%d years old"
greeter(a, a)
But it was deemed too much for the poor underscore. You'll have to write the function as in the other answer.
Your form, in which your macro sees "${a[Int]}" and writes a function with an Int param, doesn't look hard to implement.
Other features of the f-interpolator include other static error checking:
scala> f"$b%.02d"
<console>:19: error: precision not allowed
f"$b%.02d"
^
and support for Formattable:
scala> val ff = new Formattable { def formatTo(fmtr: Formatter, flags: Int, width: Int, precision: Int) = fmtr.format("%s","hello, world") }
ff: java.util.Formattable = $anon$1#d2e6b0b
scala> f"$ff"
res6: String = hello, world
A quick macro might emit (i: Int) => f"${ new Formattable {...} }".