How to pass a case-class into a function?

1,586 views
Skip to first unread message

Anatoliy Kmetyuk

unread,
May 1, 2015, 9:30:14 AM5/1/15
to scala...@googlegroups.com
Hi everyone!

I have several case classes that inherit from same trait and have same constructor parameters:

trait Base
case class First (x: Int) extends Base
case class Second(x: Int) extends Base

Now I want to have a function like follows:

def f(B: Base): Base = something match {
 
case B(x)  => B(x + 1)
 
case other => B(1)
}

f
(First)
f
(Second)

Obviously, this generates errors when applying and unapplying B and when passing First and Second into f. But the idea is clear, I suppose.

Can anyone suggest how to do this in a correct way?

Regards,
Anatoliy Kmetyuk

Nils Kilden-Pedersen

unread,
May 1, 2015, 9:39:49 AM5/1/15
to Anatoliy Kmetyuk, scala-user
def f(b: Base): Base = b match {
  case First(x) => ...
  case Second(x) => ...
}

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Anatoliy Kmetyuk

unread,
May 1, 2015, 9:49:13 AM5/1/15
to Nils Kilden-Pedersen, scala-user

This is not what I want. I don't need to pass a value of type of the case class. I want to pass the case class itself. Please look at the right-hand side of the case arrows of my sample fuction.

Daniel Armak

unread,
May 1, 2015, 10:02:34 AM5/1/15
to Anatoliy Kmetyuk, Nils Kilden-Pedersen, scala-user

You can’t pass types and match on them. But you can use TypeTags for a similar effect:

def f[B <: Base](implicit tag: TypeTag[B]): Base = {
  if (tag.tpe =:= typeOf[First]) ...
  else if (tag.tpe =:= typeOf[Second]) ...
}

f[First] // invocation

Daniel Armak

Clint Gilbert

unread,
May 1, 2015, 10:13:06 AM5/1/15
to scala...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Do you mean pass in Base's companion object? Given

class A { ... }

object A { ... }

You can refer to the type of the companion object with

A.type

so

def foo(companion: A.type): Bar = ...

On 05/01/2015 09:49 AM, Anatoliy Kmetyuk wrote:
> This is not what I want. I don't need to pass a value of type of
> the case class. I want to pass the case class itself. Please look
> at the right-hand side of the case arrows of my sample fuction.
>
> On May 1, 2015 4:39 PM, "Nils Kilden-Pedersen" <nil...@gmail.com
> <mailto:nil...@gmail.com>> wrote:
>
> |def f(b: Base): Base = b match { case First(x) => ... case
> Second(x) => ... } |
>
> On Fri, May 1, 2015 at 8:30 AM, Anatoliy Kmetyuk
> <anatoli...@gmail.com <mailto:anatoli...@gmail.com>>
> wrote:
>
> Hi everyone!
>
> I have several case classes that inherit from same trait and have
> same constructor parameters:
>
> | trait Base caseclassFirst(x:Int)extendsBase
> caseclassSecond(x:Int)extendsBase |
>
> Now I want to have a function like follows:
>
> | deff(B:Base):Base=something match { caseB(x) =>B(x +1) caseother
> =>B(1) }
>
> f(First) f(Second) |
>
> Obviously, this generates errors when applying and unapplying B and
> when passing First and Second into f. But the idea is clear, I
> suppose.
>
> Can anyone suggest how to do this in a correct way?
>
> Regards, Anatoliy Kmetyuk
>
> -- You received this message because you are subscribed to the
> Google Groups "scala-user" group. To unsubscribe from this group
> and stop receiving emails from it, send an email to
> scala-user+...@googlegroups.com
> <mailto:scala-user+...@googlegroups.com>. For more options,
> visit https://groups.google.com/d/optout.
>
> ​
>
> -- You received this message because you are subscribed to the
> Google Groups "scala-user" group. To unsubscribe from this group
> and stop receiving emails from it, send an email to
> scala-user+...@googlegroups.com
> <mailto:scala-user+...@googlegroups.com>. For more options,
> visit https://groups.google.com/d/optout.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJVQ4nkAAoJEBnktRkJHUgs52gP/09u1+L4w4lQv2X8yoRvg3SP
EFta7Lqs9B2u72V9xWawC0eya3IU8cMYNtJHc7/RW3dckONSp9JI2aJ4LnyoYxQH
2KaCi9gmhZjIYa+bzWsBg2JoSmo8ulORfhn7MaIJyy99QCyvcletlDN4xbB5VgeP
oRVMRqUmO99qH6NrkIuoiaZGdlT+ZkiLdBL+K6H/Kvc5GrgfMAVzHoYefUzO9kbM
sR5iq3itRVBP/MCxpVO3Kt6M12IAmcyR/X1fb4r8IRC2mlXQbRgg4eOc8j42ndaN
crirAv2ESscouNNj4r05rwdqoo5dpLvWVIiHRvOpFtktJ7erUKiCBC2mSRuEm74d
Sa+0qQXnrmyXlR5tlHIgoME9hcMs168ELzY/DchLUE4IycgCrOLztX2h2+cP3tH3
kKLv2QFpQ+1fpJEJKMHHSzM535gdnbx/tqf9qdAbfoJYvcBnchzolTQdbaAAiJqk
iboUJbcTP4TFj6XRreAYT6w1QyvEgjLFgU1ZyftSxgm6jIbRwbxyq9Ml1OIuH9Xn
DfmE1a13DoqE/cwnada+sfawI6FNEIrF7frHgKdivXLhcxzUafAtWPC06KtXoh/z
HYZhISrq9/uqfa+rftGaOdVXLw0U4H42ERqibCRIi02wLP4qkXp2Twm8Tk2BwlpV
Aj4ONMvTx3ESbJTThDVh
=qyAR
-----END PGP SIGNATURE-----

Roland Kuhn

unread,
May 1, 2015, 10:40:25 AM5/1/15
to Anatoliy Kmetyuk, scala-user
Hi Anatoliy,

the values you are passing to f are the companion objects not “the classes” (which cannot be passed like that). Your Base trait should define the appropriate `apply` and `unapply` methods and then your concrete classes First and Second do not extend Base, their companions do:

scala> trait Base { type T; def apply(x: Int): T; def unapply(a: Any): Option[Int] }
defined trait Base

scala> def f(B: Base, a: Any) = a match { case B(i) => B(i + 1); case other => B(0) }
f: (B: Base, a: Any)B.T

scala> case class X(x: Int); object X extends Base { def unapply(a: Any) = a match { case x: X => Some(x.x); case _ => None }; type T = X }
defined class X
defined object X

scala> f(X, "")
res3: X.T = X(0)

scala> f(X, X(1))
res4: X.T = X(2)

Regards,

Roland

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn


Reply all
Reply to author
Forward
0 new messages