Scala in intellij cannot find my function definition? - scala

I implemented a toy worksheet in intellij.
abstract class Nat:
def isZero: Boolean
def predecessor: Nat
def successor: Nat
def + (that: Nat): Nat
def - (that: Nat): Nat
end Nat
object Zero extends Nat:
def isZero: Boolean = true
def predecessor: Nat = ???
def successor: Nat = Succ(this)
def + (that: Nat): Nat = that
def - (that: Nat): Nat = if that.isZero then this else ???
override def toString = "Zero"
end Zero
class Succ(n: Nat) extends Nat:
def isZero: Boolean = false
def predecessor: Nat = n
def successor: Nat = Succ(this)
def + (that: Nat): Nat = Succ(n + that)
def - (that: Nat): Nat = if that.isZero then this else n - that.predecessor
override def toString = s"Succ($n)"
end Succ
val two = Succ(Succ(Zero)) // : Succ =
val one = Succ(Zero)
two + one
two - one
//one - two
Other worksheet has been evaluated fine so far, but when I evaluated this one, I encountered some errors show below:
// defined class Nat
4 | def successor: Nat = Succ(this)
| ^^^^
| Not found: Succ
// defined class Succ
1 |val two = Succ(Succ(Zero))
| ^^^^
| Not found: Zero
1 |val one = Succ(Zero)
| ^^^^
| Not found: Zero
1 |two + one
|^^^
|Not found: two
1 |two - one
|^^^
|Not found: two
How to resolve the not found error?

The specific problem is that worksheets are executed in order and Succ has not been defined when Zero is being defined.
More generally I suggest switching to a full App rather than a worksheet. Writing and running an App is pretty east. Create a subclass of App with your code:
object Worksheet extends App {
println("Hello world")
}
Then just click the green arrow to the left of the object and IntelliJ will compile and run the program.
Or right click and select Debug so that you can put breakpoints on key points the code and then step through line by line.

Related

IntelliJ Cannot resolve symbol n

I have the following scala code. IntelliJ says "Cannot resolve symbol n". I tried "File | Invalidate " trick but it didn't solve the issue.
abstract class Nat {
def isZero: Boolean
def predecessor: Nat
def successor: Nat = new Succ(this)
def +(that: Nat): Nat
def -(that: Nat): Nat
}
object Succ (n: Nat) extends Nat {
def isZero: Boolean = false
def predecessor: Nat = n
def +(that: Nat) = new Succ(n + that)
def -(that: Nat): Nat = if (that.isZero) this else n - that.predecessor
}
You cannot have parameters for an object Succ. use class instead.
class Succ (n: Nat) extends Nat {
def isZero: Boolean = false
def predecessor: Nat = n
def +(that: Nat) = new Succ(n + that)
def -(that: Nat): Nat = if (that.isZero) this else n - that.predecessor
}
Objects in Scala cannot take parameters. This is not valid Scala code. This also applies to traits. If you need to pass constructor parameters then use a class.

Scala type mismatch using multiple generic

I'm trying to use Scala to prototype the functionality of lazy endless list for my lambda calculus classes. The public constructor takes two arguments and should create LazyList[A,A].
class LazyList[A,B] private (private val first: A, private val mapper: A => B, private val successor: A => A) {
def this(first: A, successor: A => A) = this(first, (e: A) => e, successor)
def head: B = mapper(first)
def tail(): LazyList[A,B] = new LazyList(successor(first), mapper, successor)
def map[R](func: B => R) = new LazyList[A, R](first, func.compose(mapper), successor)
def at(index: Long): B = if (index == 0L) head else tail().at(index - 1)
def sublist(end: Long): List[B] = if (end == 0L) List(head) else head :: tail().sublist(end - 1)
override def toString = s"LazyList($first, $mapper, $successor)"
}
But the code compilation fails with error.
Error:(20, 65) type mismatch;
found : e.type (with underlying type A)
required: B
def this(first: A, successor: A => A) = this(first, (e: A) => e, successor)
^
What actually am I doing wrong?
Parameterized signatures inside the class don't have any info about the relation of type B to type A, and thus the compiler generally thinks that everywhere inside the LazyList's body B is not A, that's why it compiler complains when you try to assign A => A to A => B.
You should create an alternative constructor not as this(), but as a factory method in companion object. Note the A of this usage is a parameter which is not in any way related to the A inside LazyList's body:
object LazyList {
def apply[A](first: A, successor: A => A): LazyList[A, A] = new LazyList(first, identity, successor)
}

Generic Adder from Idris to Scala?

Type Driven Development with Idris presents the following generic adder approach:
AdderType : (numArgs : Nat) -> Type
AdderType Z = Int
AdderType (S k) = (next : Int) -> AdderType k
adder : (n : Nat) -> (acc : Int) -> AdderType n
adder Z acc = acc
adder (S k) acc = \x => (adder k (x+acc))
Example:
-- expects 3 Int's to add, with a starting value of 0
*Work> :t (adder 3 0)
adder 3 0 : Int -> Int -> Int -> Int
-- 0 (initial) + 3 + 3 + 3 == 9
*Work> (adder 3 0) 3 3 3
9 : Int
I'm guessing that shapeless can handle the above generic adder function.
How can it be written in Scala with or without shapeless?
Update: I'll leave my original implementation below, but here's one that's a little more direct:
import shapeless._
trait AdderType[N <: Nat] extends DepFn1[Int]
object AdderType {
type Aux[N <: Nat, Out0] = AdderType[N] { type Out = Out0 }
def apply[N <: Nat](base: Int)(implicit at: AdderType[N]): at.Out = at(base)
implicit val adderTypeZero: Aux[Nat._0, Int] = new AdderType[Nat._0] {
type Out = Int
def apply(x: Int): Int = x
}
implicit def adderTypeSucc[N <: Nat](implicit
atN: AdderType[N]
): Aux[Succ[N], Int => atN.Out] = new AdderType[Succ[N]] {
type Out = Int => atN.Out
def apply(x: Int): Int => atN.Out = i => atN(x + i)
}
}
And then:
scala> val at3 = AdderType[Nat._3](0)
at3: Int => (Int => (Int => Int)) = <function1>
scala> at3(3)(3)(3)
res8: Int = 9
Original answer below.
Here's an off-the-cuff Scala translation:
import shapeless._
trait AdderType[N <: Nat] extends DepFn1[Int] {
protected def plus(x: Int): AdderType.Aux[N, Out]
}
object AdderType {
type Aux[N <: Nat, Out0] = AdderType[N] { type Out = Out0 }
def apply[N <: Nat](base: Int)(implicit at: AdderType[N]): Aux[N, at.Out] =
at.plus(base)
private[this] case class AdderTypeZero(acc: Int) extends AdderType[Nat._1] {
type Out = Int
def apply(x: Int): Int = acc + x
protected def plus(x: Int): Aux[Nat._1, Int] = copy(acc = acc + x)
}
private[this] case class AdderTypeSucc[N <: Nat, Out0](
atN: Aux[N, Out0],
acc: Int
) extends AdderType[Succ[N]] {
type Out = Aux[N, Out0]
def apply(x: Int): Aux[N, Out0] = atN.plus(acc + x)
protected def plus(x: Int): Aux[Succ[N], Aux[N, Out0]] = copy(acc = acc + x)
}
implicit val adderTypeZero: Aux[Nat._1, Int] = AdderTypeZero(0)
implicit def adderTypeSucc[N <: Nat](implicit
atN: AdderType[N]
): Aux[Succ[N], Aux[N, atN.Out]] = AdderTypeSucc(atN, 0)
}
And then:
scala> val at3 = AdderType[Nat._3](0)
at3: AdderType[shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]]] { ...
scala> at3(3)(3)(3)
res0: Int = 9
It's more verbose and the representation is a little different to get the Scala syntax to work out—our "base case" is essentially an Int => Int instead of an Int because otherwise I don't see a way to avoid needing to write apply or () everywhere—but the basic ideas are exactly the same.
In case you're on a long trip and don't have your shapeless on hands, here is how you can do this in pure Scala. It can be useful for those who are not familiar with shapeless and those who don't use it for some reason.
First of all, we'll need some way to iterate on types, i.e. represent natural numbers in types. You can use any nested type or just define a new one with some aliases for numbers:
sealed trait Nat
trait Zero extends Nat
trait Succ[N <: Nat] extends Nat
// enough for examples:
type _0 = Zero
type _1 = Succ[_0]
type _2 = Succ[_1]
type _3 = Succ[_2]
type _4 = Succ[_3]
// etc...
Of course, if you will often use types like _42 and _342923, it would be more convenient to take an existing Nat type with some macro-magic for constructing those from values, but for our examples it's enough.
Now, the AdderType dependent function type is quite straight forward:
// first we define the type which take a Nat type argument
trait AdderType[N <: Nat] {
type Out
def apply(i: Int): Out
}
// then we inductively construct its values using implicits
case object AdderType {
// base case: N = _0
implicit def zero:
AdderType[_0] { type Out = Int } =
new AdderType[_0] {
type Out = Int
def apply(i: Int): Out = i
}
// induction step: N -> Succ[N]
implicit def succ[N <: Nat, NOut](
implicit prev: AdderType[N] { type Out = NOut }
): AdderType[Succ[N]] { type Out = Int => NOut } =
new AdderType[Succ[N]] {
type Out = Int => NOut
def apply(i: Int): Out = k => prev(i + k)
}
}
Now, to construct an instance of AdderType and apply it, we write a function, which takes a N <: Nat as a type argument and implicitly constructs AdderType[N]:
def adder[N <: Nat](initial: Int)(
implicit adderFunction: AdderType[N]
): adderFunction.Out = adderFunction(initial)
That's it:
scala> val add3Numbers = adder_[_3](0)
add3Numbers: Int => (Int => (Int => Int)) = <function1>
scala> add3Numbers(1)(2)(3)
res0: Int = 6
You can see that the pure solution is not much bigger or more complicated than the one using shapeless (although the latter provides us ready-to-use Nat and DepFn types).
A little addition: if (in some more general case) you don't want to use adderFunction.Out, which sometimes leads to problems, I also have a solution without it. In this particular case it's not any better, but I'll show it anyway.
The key point is to add another type parameter for the out type: adder[N <: Nat, NOut], but then can't pass N as a type to adder, because we will need to write NOut, which want to be inferred (otherwise, what's the point). So we can pass an additional value argument, which will help to derive N type:
def adder[N <: Nat, NOut](n: NatVal[N])(initial: Int)(
implicit adderFunction: AdderType[N] { type Out = NOut }
): NOut = adderFunction(initial)
To construct NatVal[N] we don't need to create an instance of each Nat type, we can use a little trick:
// constructing "values" to derive its type arg
case class NatVal[N <: Nat]()
// just a convenience function
def nat[N <: Nat]: NatVal[N] = NatVal[N]()
Now here is how you use it:
scala> val add3Numbers = adder(nat[_3])(0)
add3Numbers: this.Out = <function1>
scala> add3Numbers(1)(2)(3)
res1: this.Out = 6
You can see that it works, but doesn't show us the actual types. Nevertheless, this approach can work better in cases when you have several implicits that depend others' type members. I mean
def foo[AOut]()(implicit
a: A { type Out = AOut},
b: B { type In = AOut }
) ...
instead of
def foo()(implicit
a: A,
b: B { type In = a.Out }
) ...
Because you cannot reffer to a.Out in the same argument list.
You can find full code in my repo on Github.

Partially applied Function2 with first and second argument

Given a method
def f(a: String, b: String) = ???
I want to get both partially applied function (with first argument and with the second one).
I've written the following code :
def fst = f _ curried "a"
def snd = (s: String) => (f _ curried)(s)("b")
Is there a better way ?
[update] snd could be written shorter def snd = (f _ curried)((_: String))("b")
This is simpler:
def fst = f("a", (_: String))
def snd = f((_: String), "b")
But note it recalculates the partially applied functions on every call, so I'd prefer val (or maybe lazy val) instead of def in most circumstances.
Another way to do it is to use multiple parameter lists:
def f(a: String)(b: String) = ???
No args supplied:
def fst = f _
First arg supplied:
def fst = f("a")
Only second arg supplied:
def fst = f(_: String)("b")
All args supplied:
def snd = f("a")("b")
If you are currying args in the same order they are defined then this syntax is a bit cleaner than the one used in the question.

Extractor for a shapeless HList that mimics parser concatenation `~`

Question
Is it somehow possible to create an extractor for shapeless' HList that looks like the following.
val a ~ _ ~ b = 4 :: "so" :: 4.5 :: HNil
=> a == 4 && b == 4.5
Replace :: by ~, which shouldn't be the problem.
Get rid of the terminating HNil. Are there any problems that might arise?
Motivation
After much sweat and tears I managed to arrive at the point, where the following code works:
for(
x1 :: _ :: x2 :: HNil <- (expInt ~ "+" ~ expInt).llE
) yield (x1 + x2)
expInt parses an Int in some monad E. The type of (expInt ~ "+" ~ expInt).llE is E[Int :: String :: Int :: HNil].
I want the pattern on the left of the <- to somehow resemble the construction of the combinator parser on the right.
This can be done, and has a couple of interesting twists.
The first is that, typically, for matching a structure that's built with a right associative constructor (ie. ::) you would use a correspondingly right associative extractor, otherwise you would decompose and bind the extracted elements in reverse order. Unfortunately right associative extractors must, like right associative operators, end with a : in Scala and that would clobber your parser combinator syntax since the extractor name would have to be ~: instead of plain ~. However, I'll postpone this for the moment and work with right associativity.
The second twist is that we need the unapply method to yield results of different types depending on whether we're matching an HList of more than two elements or of exactly two elements (and we shouldn't be able to match a list of less that two elements at all).
If we're matching a list of more than two elements we need to decompose the list into a pair consisting of the head and the HList tail, ie. given l: H :: T where T <: HList we must yield a value of type (H, T). If, on the other hand, we're matching a list of exactly two elements, ie. of the form E1 :: E2 :: HNil, we need to decompose the list into a pair consisting of just those two elements, ie (E1, E2) rather than a head and a tail which would be (E1, E2 :: HNil).
This can be done using exactly the same type level programming techniques that are used throughout shapeless. First we define a type class which is going to do the work of the extractor, with instances corresponding to each of the two cases described above,
import shapeless._
trait UnapplyRight[L <: HList] extends DepFn1[L]
trait LPUnapplyRight {
type Aux[L <: HList, Out0] = UnapplyRight[L] { type Out = Out0 }
implicit def unapplyHCons[H, T <: HList]: Aux[H :: T, Option[(H, T)]] =
new UnapplyRight[H :: T] {
type Out = Option[(H, T)]
def apply(l: H :: T): Out = Option((l.head, l.tail))
}
}
object UnapplyRight extends LPUnapplyRight {
implicit def unapplyPair[H1, H2]: Aux[H1 :: H2 :: HNil, Option[(H1, H2)]] =
new UnapplyRight[H1 :: H2 :: HNil] {
type Out = Option[(H1, H2)]
def apply(l: H1 :: H2 :: HNil): Out = Option((l.head, l.tail.head))
}
}
Then we define our extractor in terms of it like so,
object ~: {
def unapply[L <: HList, Out](l: L)
(implicit ua: UnapplyRight.Aux[L, Out]): Out = ua(l)
}
And then we're good to go,
val l = 23 :: "foo" :: true :: HNil
val a ~: b ~: c = l
a : Int
b : String
c : Boolean
So far, so good. Now let's return to the associativity issue. If we want to achieve the same effect with a left associative extractor (ie. ~ instead of ~:) we'll need to change the way the decomposition is done. First let's desugar the right associative extractor syntax we just used. The expression,
val a ~: b ~: c = l
is equivalent to,
val ~:(a, ~:(b, c)) = l
By contrast, the left associative version,
val a ~ b ~ c = l
is equivalent to,
val ~(~(a, b), c) = l
To make this work as an extractor for HLists our unapply type class must peel elements off from the end, rather from beginning of the list. We can do this with the aid of shapeless's Init and Last type classes,
trait UnapplyLeft[L <: HList] extends DepFn1[L]
trait LPUnapplyLeft {
import ops.hlist.{ Init, Last }
type Aux[L <: HList, Out0] = UnapplyLeft[L] { type Out = Out0 }
implicit def unapplyHCons[L <: HList, I <: HList, F]
(implicit
init: Init.Aux[L, I],
last: Last.Aux[L, F]): Aux[L, Option[(I, F)]] =
new UnapplyLeft[L] {
type Out = Option[(I, F)]
def apply(l: L): Out = Option((l.init, l.last))
}
}
object UnapplyLeft extends LPUnapplyLeft {
implicit def unapplyPair[H1, H2]: Aux[H1 :: H2 :: HNil, Option[(H1, H2)]] =
new UnapplyLeft[H1 :: H2 :: HNil] {
type Out = Option[(H1, H2)]
def apply(l: H1 :: H2 :: HNil): Out = Option((l.head, l.tail.head))
}
}
object ~ {
def unapply[L <: HList, Out](l: L)
(implicit ua: UnapplyLeft.Aux[L, Out]): Out = ua(l)
}
And now we're done,
val a ~ b ~ c = l
a : Int
b : String
c : Boolean