Scala 高阶函数
Scala High Order Function
我想将函数作为 class 构造的参数。
我有一些函数想在 class 中计算(某种惰性计算)
class Foo(calc: PGSimpleDataSource => Connection => PreparedStatement => ResultSet => Option[A] ??? ) {
here some logic like:
def runCalc = calc ( resultSet ( preparedStatement ( connection )
resultSet.close()
preparedStatement.close()
connection.close()
send result somewhere ...
}
准备一些函数
implicit val dataSource: PGSimpleDataSource = Service.ds
implicit def getConnection(implicit ds: PGSimpleDataSource): Connection = ds.getConnection
implicit def getPreparedStatement(userId: UUID)(implicit con: Connection): PreparedStatement ={
val st = con.prepareStatement("SELECT * FROM bar WHERE id = CAST(? as UUID)")
st.setString(1, id.toString)
st
}
implicit def getResultSet(implicit ps: PreparedStatement): ResultSet = ps.executeQuery()
implicit def mapping(implicit rs: ResultSet): Option[Bar] = {
Iterator.continually(rs.next)
.takeWhile(identity)
.map(_ => Bar(UUID.fromString(rs.getString(1)))).toList.headOption
}
然后是一些功能,例如:
def getInstance(id: UUID) = new Foo(???)
val foo = getInstance(id)
foo.runCalc()
可能吗?请帮忙
更新:
我试过这样 class :
class Foo[A](
con: => Connection,
ps: => PreparedStatement,
rs: => ResultSet,
mapping: => Option[A],
calc: Connection => PreparedStatement => ResultSet => Option[A]
) {
def run(): Unit = {
val result: Option[A] = calc(con)(ps)(rs)(mapping)
rs.close()
ps.close()
con.close()
}
}
但我不明白如何编写 "f" 函数,如下所示
它需要做映射( getResultSet ( getPreparedStatement (id, getConnection))
换句话说,映射需要 ResultSet,需要 PreparedStatement,需要 Id 和 Connection
你可以的。看起来像这样
case class Foo(calc: String => String => String => Option[String]) {
def run = {
val p1 = "p1"
val p2 = "p2"
val p3 = "p3"
calc(p1)(p2)(p3)
}
}
使用示例
object App extends App {
val f = (x: String) => (y: String) => (z: String) => {
Option(x + y + z)
}
val foo = Foo(f)
println(foo.run)
}
或者你可以使用柯里化
object App extends App {
val f = (x: String, y: String, z: String) => {
Option(x + y + z)
}
val foo = Foo(f.curried)
println(foo.run)
}
编辑
对于你的扩展问题,我可以提出这个 class:
case class Foo[A](
getConnection: () => Connection,
getStatement: Connection => PreparedStatement,
getResultSet: PreparedStatement => ResultSet,
mapping: ResultSet => Option[A]) {
def run(): Option[A] = {
val connection = getConnection()
try{
val statement = getStatement(connection)
try{
val resultSet = getResultSet(statement)
try{
mapping(resultSet)
}finally {
resultSet.close()
}
}finally{
statement.close()
}
} finally {
connection.close()
}
}
}
用法示例:
val foo = Foo(
() => new Connection(),
connection => new PreparedStatement(),
statement => new ResultSet(),
resultSet => Option("")
)
所有这些函数都有上一步的参数,因此当您创建 ResultSet
时,您可以使用 statement
(但不能使用 connection
)。
我想将函数作为 class 构造的参数。 我有一些函数想在 class 中计算(某种惰性计算)
class Foo(calc: PGSimpleDataSource => Connection => PreparedStatement => ResultSet => Option[A] ??? ) {
here some logic like:
def runCalc = calc ( resultSet ( preparedStatement ( connection )
resultSet.close()
preparedStatement.close()
connection.close()
send result somewhere ...
}
准备一些函数
implicit val dataSource: PGSimpleDataSource = Service.ds
implicit def getConnection(implicit ds: PGSimpleDataSource): Connection = ds.getConnection
implicit def getPreparedStatement(userId: UUID)(implicit con: Connection): PreparedStatement ={
val st = con.prepareStatement("SELECT * FROM bar WHERE id = CAST(? as UUID)")
st.setString(1, id.toString)
st
}
implicit def getResultSet(implicit ps: PreparedStatement): ResultSet = ps.executeQuery()
implicit def mapping(implicit rs: ResultSet): Option[Bar] = {
Iterator.continually(rs.next)
.takeWhile(identity)
.map(_ => Bar(UUID.fromString(rs.getString(1)))).toList.headOption
}
然后是一些功能,例如:
def getInstance(id: UUID) = new Foo(???)
val foo = getInstance(id)
foo.runCalc()
可能吗?请帮忙
更新:
我试过这样 class :
class Foo[A](
con: => Connection,
ps: => PreparedStatement,
rs: => ResultSet,
mapping: => Option[A],
calc: Connection => PreparedStatement => ResultSet => Option[A]
) {
def run(): Unit = {
val result: Option[A] = calc(con)(ps)(rs)(mapping)
rs.close()
ps.close()
con.close()
}
}
但我不明白如何编写 "f" 函数,如下所示
它需要做映射( getResultSet ( getPreparedStatement (id, getConnection))
换句话说,映射需要 ResultSet,需要 PreparedStatement,需要 Id 和 Connection
你可以的。看起来像这样
case class Foo(calc: String => String => String => Option[String]) {
def run = {
val p1 = "p1"
val p2 = "p2"
val p3 = "p3"
calc(p1)(p2)(p3)
}
}
使用示例
object App extends App {
val f = (x: String) => (y: String) => (z: String) => {
Option(x + y + z)
}
val foo = Foo(f)
println(foo.run)
}
或者你可以使用柯里化
object App extends App {
val f = (x: String, y: String, z: String) => {
Option(x + y + z)
}
val foo = Foo(f.curried)
println(foo.run)
}
编辑
对于你的扩展问题,我可以提出这个 class:
case class Foo[A](
getConnection: () => Connection,
getStatement: Connection => PreparedStatement,
getResultSet: PreparedStatement => ResultSet,
mapping: ResultSet => Option[A]) {
def run(): Option[A] = {
val connection = getConnection()
try{
val statement = getStatement(connection)
try{
val resultSet = getResultSet(statement)
try{
mapping(resultSet)
}finally {
resultSet.close()
}
}finally{
statement.close()
}
} finally {
connection.close()
}
}
}
用法示例:
val foo = Foo(
() => new Connection(),
connection => new PreparedStatement(),
statement => new ResultSet(),
resultSet => Option("")
)
所有这些函数都有上一步的参数,因此当您创建 ResultSet
时,您可以使用 statement
(但不能使用 connection
)。