Skip to content

Instantly share code, notes, and snippets.

@sarkologist
Last active April 26, 2018 12:15
Show Gist options
  • Save sarkologist/4522e849a5fe4453cc2044566849cc28 to your computer and use it in GitHub Desktop.
Save sarkologist/4522e849a5fe4453cc2044566849cc28 to your computer and use it in GitHub Desktop.
first sketch of free applicative config in scala
import com.typesafe.config.{Config, ConfigFactory}
object Configured extends App {
val config = ConfigFactory.load()
import TypesafeConfig._
import FreeConfig._
import scalaz.syntax.apply._
val kafkaProducerBackoff: BackoffConfig[KafkaProducerBackoff] =
runWith(config)(
(("kafka-producer.backoff.min" by (_.getDuration(_)) map toFiniteDuration) |@|
("kafka-producer.backoff.max" by (_.getDuration(_)) map toFiniteDuration) |@|
("kafka-producer.backoff.factor" by (_.getDouble(_))))(
BackoffConfig.apply[KafkaProducerBackoff]
)
)
}
object TypesafeConfig {
trait KafkaProducerBackoff
case class BackoffConfig[T](
minBackoff: FiniteDuration,
maxBackoff: FiniteDuration,
randomFactor: Double
)
}
object FreeConfig {
case class FreeConfig[T](parse: Config => T)
import scalaz.FreeAp._
import scalaz.{ FreeAp, NaturalTransformation }
import scalaz.Id._
import scalaz.{ Value }
implicit class LiftTypesafePath[T](path: String) {
def by(parse: (Config, String) => T) = lift(FreeConfig(parse(_, path)))
}
def toFiniteDuration(d: java.time.Duration): FiniteDuration = Duration.fromNanos(d.toNanos)
def reading(config: Config) = new NaturalTransformation[FreeConfig, Identity] {
override def apply[A](fa: FreeConfig[A]) = Value(fa.parse(config))
}
def runWith[T](config: Config)(freeConfig: FreeAp[FreeConfig, T]): T =
freeConfig.foldMap(reading(config)).value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment