1

Here I am adding a new method to to LocalDate:

object EnhancedDate {
  implicit class EnhancedDate(start: org.joda.time.LocalDate) {
    /** Generates dates between start and end - inclusive */
    def to(end: org.joda.time.LocalDate): IndexedSeq[org.joda.time.LocalDate] = {
      val numberOfDays = Days.daysBetween(start, end.plusDays(1)).getDays()
      for (f <- 0 to numberOfDays) yield start.plusDays(f)
    }
  }
}

and now using it:

import cats.effect.IO
import EnhancedDate.EnhancedDate

def loadCadUsdRates: IO[Map[String, CadInUsd]] = IO {
  val start = new org.joda.time.LocalDate(startYear,1,1)
  val end = new org.joda.time.LocalDate(endYear+1,1,1).minusDays(1)
  start to end map(f) toMap 
}

Function f doesn't really matter; you can use identity for all it's worth bc the results are the same.
I use Idea and everything is fine in the IDE (no red underlyings) but when I run it I get this error:

Error:(104, 9) value to is not a member of org.joda.time.LocalDate
start to end map(f) toMap

Now I've used pimp my library before and I'm pretty sure this is the right way to do it, but there must be something about joda date that is incompatible with it... Have you tried pimping Joda LocalDate.. I do not know why this is not working

Jeffrey Chung
  • 19,319
  • 8
  • 34
  • 54
Adrian
  • 5,603
  • 8
  • 53
  • 85
  • 1
    When debugging implicits, it helps to try applying the implicit explicitly: `new EnhancedDate(start) to end`... and see if that works. Just while debugging of course. – Alvaro Carrasco Nov 27 '17 at 15:49
  • @AlvaroCarrasco thanks for the hint. It works fine if I do it this way.. – Adrian Nov 27 '17 at 15:54
  • 1
    What is `EnhancedDate` (top level)? a package? an object? is it in a separate file? – Alvaro Carrasco Nov 27 '17 at 16:47
  • @Alvaro - see my answer. I suspect that it's a module and that this is why it is not working - name resolution issues – oxbow_lakes Nov 27 '17 at 17:03
  • @AlvaroCarrasco apologies for the copy and paste error; it's an object – Adrian Nov 27 '17 at 17:04
  • Possible duplicate of [Adding a Typeclass to Java enum - without simulacrum](https://stackoverflow.com/questions/41917445/adding-a-typeclass-to-java-enum-without-simulacrum) – Jasper-M Nov 27 '17 at 17:23

1 Answers1

3

I'm not exactly sure what is going on here but it's something to do with the declaration being a module with the same name as the implicit class within it. This means that you have two identifiers in scope, both called EnhancedDate and I assume that this must cause resolution ambiguity. It's certainly nothing to do with Joda. One definite workaround is to place your implicit class inside the nearest package object.

package object myPackage {
  implicit class EnhancedDate(start: org.joda.time.LocalDate) { ... }
}

Here's a demonstration of it not working:

scala> :paste
// Entering paste mode (ctrl-D to finish)

object Foo {
  implicit class Foo(s: String) { def foo = println(s"Foo: $s") }
}

// Exiting paste mode, now interpreting.

defined object Foo

scala> import Foo._
import Foo._

scala> "hey".foo
<console>:14: error: value foo is not a member of String
       "hey".foo
             ^

Here is it working:

scala> object Bar {
     | implicit class Foo(s: String) { def foo = println(s"Foo: $s") }
     | }
defined object Bar

scala> import Bar._
import Bar._

scala> "hey".foo
Foo: hey
oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449