All Downloads are FREE. Search and download functionalities are using the official Maven repository.

instances.RecordInstances.scala Maven / Gradle / Ivy

The newest version!
package jjm.instances

import jjm.metrics.HasMetrics
import jjm.metrics.MapTree
import jjm.metrics.Metric

import cats.Monoid
import cats.kernel.CommutativeMonoid
import cats.implicits._

import shapeless.HList
import shapeless.HNil
import shapeless.::
import shapeless.Witness
import shapeless.labelled.FieldType
import shapeless.labelled.field

trait RecordInstances extends LowPriorityRecordInstances {

  final implicit def hnilCommutativeMonoid: CommutativeMonoid[HNil] =
    new CommutativeMonoid[HNil] {
      def empty = HNil
      def combine(x: HNil, y: HNil) = HNil
    }

  final implicit def hconsRecordCommutativeMonoid[K, H: CommutativeMonoid, Tail <: HList : CommutativeMonoid]: CommutativeMonoid[FieldType[K, H] :: Tail] =
    new CommutativeMonoid[FieldType[K, H] :: Tail] {
      def empty = field[K](CommutativeMonoid[H].empty) :: CommutativeMonoid[Tail].empty
      def combine(x: FieldType[K, H] :: Tail, y: FieldType[K, H] :: Tail) =
        field[K]((x.head: H) |+| (y.head: H)) :: (x.tail |+| y.tail)
    }

  sealed trait RecordHasMetrics[R <: HList] {
    def apply(r: R): List[(String, MapTree[String, Metric])]
  }
  final object RecordHasMetrics {
    implicit def hnilHasMetrics: RecordHasMetrics[HNil] =
      new RecordHasMetrics[HNil] {
        def apply(r: HNil) = Nil
      }
    implicit def hconsHasMetrics[K <: String, V, Tail <: HList](
      implicit key: Witness.Aux[K],
      valueHasMetrics: HasMetrics[V],
      tailHasMetrics: RecordHasMetrics[Tail]
    ): RecordHasMetrics[FieldType[K, V] :: Tail] =
      new RecordHasMetrics[FieldType[K, V] :: Tail] {
        def apply(r: FieldType[K, V] :: Tail) = (key.value, valueHasMetrics.getMetrics(r.head)) :: tailHasMetrics(r.tail)
      }
  }
  final implicit def recordHasMetrics[R <: HList](implicit recordHasMetrics: RecordHasMetrics[R]): HasMetrics[R] = new HasMetrics[R] {
    def getMetrics(rec: R): MapTree[String, Metric] = {
      MapTree.fork(recordHasMetrics(rec).toMap)
    }
  }
}

trait LowPriorityRecordInstances {
  final implicit def hnilMonoid: Monoid[HNil] =
    new Monoid[HNil] {
      def empty = HNil
      def combine(x: HNil, y: HNil) = HNil
    }

  final implicit def hconsRecordMonoid[K, H: Monoid, Tail <: HList : Monoid]: Monoid[FieldType[K, H] :: Tail] =
    new Monoid[FieldType[K, H] :: Tail] {
      def empty = field[K](Monoid[H].empty) :: Monoid[Tail].empty
      def combine(x: FieldType[K, H] :: Tail, y: FieldType[K, H] :: Tail) =
        field[K]((x.head: H) |+| (y.head: H)) :: (x.tail |+| y.tail)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy