F# 如何约束为非函数?
我正在编写将F# 如何约束为非函数?,f#,F#,我正在编写将System.Data.IDbConnection及其同级抽象出来的代码 目标代码 let inline runWithConnection connector f = match connector with | ICon con -> f con | CString cs -> use conn = new SqlConnection(cs) openConnectio
System.Data.IDbConnection
及其同级抽象出来的代码
目标代码
let inline runWithConnection connector f =
match connector with
| ICon con -> f con
| CString cs ->
use conn = new SqlConnection(cs)
openConnection conn
f conn
我可以看到类型约束编译并运行,但约束到对象并没有达到预期的效果。我想约束到一个对象或值,它不是一个需要更多输入才能返回某些内容的函数。另一种编写方法是,如果它确实返回函数,则可能创建的连接在f完成之前不会关闭
let inline runWithConnection connector (f:_ -> 't when 't :> obj) =
match connector with
| ICon con -> f con
| CString cs ->
use conn = new SqlConnection(cs)
openConnection conn
f conn
您可以说't:not struct
,但不能说't:not delegate
我想做
f.GetType()
,但是我不知道像.IsClass
,.isastract
,.IsValue
这样的类型属性会与委托类型一致,而不是与其他简单类型一致。另外,这将是运行时而不是编译时,并不能真正改善这种情况。我想您的意思是,当您使用一个curriedf
调用runWithConnection
时,这不起作用,因为在返回第一个部分函数后处理连接
没有泛型约束可以解决这个问题,因为您不能约束到不是某个东西的类型,即函数。在F#、C#、Java等方面也是如此
您可能会抛出运行时异常,但我认为重新访问您正在尝试的模式要容易得多。我想问一下,让外部函数执行它传递的函数,而不仅仅是将生成的连接作为IDisposable
返回,可以保存什么。这将允许调用函数控制连接的范围,例如:
use conn = getConnection myConnector
doSomethingWithConnection conn anotherArg
请注意,您的问题不仅限于函数返回类型,还有很多“普通”类型也存在问题。考虑< <代码> f>代码> <代码>(Fix-CON-> [CONN])——然后您只返回一个列表,但是存储在该列表中的连接将在函数返回时关闭。同样,您可以创建一个类类型
ConnectionUser
,它的构造函数接受并存储一个连接,并且它的方法/属性使用它,出于同样的原因,它不能作为f
的返回类型。所以我同意你应该尝试提出一个更清晰的抽象概念
顺便说一句,我不认为
inline
在这里给你买了什么,所以你可以放心地放弃它。我不清楚你想做什么,但我怀疑你会想看看这个类。一般来说,我认为你无法判断结果是否是“纯值”。您可以尝试查看结果是否是FSharpFunc
(这是所有F#函数的实例),但这不会阻止调用方将函数包装到数据结构中,这是一个常见的模式。你可以找到一个概述-也许你只是想要no struct
约束?顺便说一句:你可以尝试将这一切都包装到你自己的DSL中-但老实说,我只会在那里写一条评论,告诉用户不要使用延迟操作,因为连接将被处理是的-老实说,我并不确切知道你有什么样的问题?这就是为什么我做了两个不同的评论