pakoito
08/31/2019, 8:48 PMBob Glamm
08/31/2019, 9:44 PMsealed class FrExpr<T>
data class FrInt(val param: String): FrExpr<Int>()
data class FrLong(val param: String): FrExpr<Long>()
data class FrString(val param: String): FrExpr<String>()
data class FrLit(val queryFragment: String): FrExpr<Nothing>()
interface FrAlgebra<RESTYPE, G> {
val MG: Monad<G>
val MB: Monoid<RESTYPE>
fun interp(frs: List<FrExpr<*>>): Kind<G, RESTYPE>
}
class FrQueryConstructor: FrAlgebra<String, ForId> {
override val MB = String.monoid()
override val MG = Id.monad()
override fun interp(frs: List<FrExpr<*>>) =
frs.foldMapM(MG, MB) { fr -> when(fr) {
is FrInt -> Id.just(" :${fr.param}: ")
is FrLong -> Id.just(" :${fr.param}: ")
is FrString -> Id.just(" :${fr.param}: ")
is FrLit -> Id.just(fr.queryFragment)
} }
}
fun main() {
val x = listOf(
FrLit("SELECT sum, cc FROM foo WHERE idx1="),
FrInt("idx1"),
FrLit(" AND idx2="),
FrLong("idx2"),
FrLit(" AND cc LIKE("),
FrString("pattern"),
FrLit(")")
)
with(FrQueryConstructor()) {
println(interp(x))
}
}
Bob Glamm
08/31/2019, 9:45 PMId(value=SELECT sum, cc FROM foo WHERE idx1= :idx1: AND idx2= :idx2: AND cc LIKE( :pattern: ))
as expected, with the idea that actual algebras would produce a query string and a program (probably eventually in IO
) that takes typed parameters and would result in the JDBC binding when run. Does that seem like the right track to you in the absence of Shapeless/etc.?Bob Glamm
08/31/2019, 9:46 PMlistOf(FrLit(...), FrInt(...), ...)
)Bob Glamm
09/01/2019, 1:06 AMBob Glamm
09/01/2019, 1:32 AM