Last active
March 31, 2020 20:49
-
-
Save johnynek/2432e2e61221cbf9e56fc4d784c3fac7 to your computer and use it in GitHub Desktop.
using literal types in scala 2.13 to track the half-life of an exponential decay
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Timestamp(epochMillis: Long) | |
case class Decay[H <: Double](scaledTime: Double, value: Double) { | |
def timestampDouble(implicit v: ValueOf[H]): Double = | |
scaledTime * v.value | |
def timestamp(implicit v: ValueOf[H]): Timestamp = | |
Timestamp(timestampDouble.toLong) | |
def combine(that: Decay[H]): Decay[H] = | |
if (scaledTime > that.scaledTime) that.combine(this) | |
else { | |
// we know scaledTime <= that.scaledTime | |
val decayThis = math.exp(scaledTime - that.scaledTime) * value | |
if (decayThis == 0.0) that | |
else Decay[H](that.scaledTime, that.value + decayThis) | |
} | |
} | |
object Decay { | |
def build[H <: Double: ValueOf, N: Numeric](time: Timestamp, n: N): Decay[H] = | |
Decay(time.epochMillis.toDouble / valueOf[H], implicitly[Numeric[N]].toDouble(n)) | |
implicit def monoidForDecay[H <: Double]: Monoid[Decay[H]] = | |
new Monoid[Decay[H]] { | |
val empty = Decay[H](Double.NegativeInfinity, 0.0) | |
def combine(l: Decay[H], r: Decay[H]): Decay[H] = l.combine(r) | |
} | |
} |
yeah, unfortunately, I posted before I ironed out usability.
Change apply
to def build
because currently you are getting confused with the apply method. (also I wouldn't use the implicit conversion).
That works better (and makes more sense ;) Thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Interesting. I haven't played with this construct before.
I had to make a few modifications to get it to compile (Scala 2.13.1):
Even then, I'm not sure how to instantiate a
Decay
:The
Decay[Nothing]
inferred type seems wrong (?). I got the same behavior indotr
, too.