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