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
这样的类型属性会与委托类型一致,而不是与其他简单类型一致。另外,这将是运行时而不是编译时,并不能真正改善这种情况。

我想您的意思是,当您使用一个curried
f
调用
runWithConnection
时,这不起作用,因为在返回第一个部分函数后处理连接

没有泛型约束可以解决这个问题,因为您不能约束到不是某个东西的类型,即函数。在F#、C#、Java等方面也是如此

您可能会抛出运行时异常,但我认为重新访问您正在尝试的模式要容易得多。我想问一下,让外部函数执行它传递的函数,而不仅仅是将生成的连接作为
IDisposable
返回,可以保存什么。这将允许调用函数控制连接的范围,例如:

use conn = getConnection myConnector
doSomethingWithConnection conn anotherArg

请注意,您的问题不仅限于函数返回类型,还有很多“普通”类型也存在问题。考虑< <代码> f>代码> <代码>(Fix-CON-> [CONN])——然后您只返回一个列表,但是存储在该列表中的连接将在函数返回时关闭。同样,您可以创建一个类类型
ConnectionUser
,它的构造函数接受并存储一个连接,并且它的方法/属性使用它,出于同样的原因,它不能作为
f
的返回类型。所以我同意你应该尝试提出一个更清晰的抽象概念


顺便说一句,我不认为
inline
在这里给你买了什么,所以你可以放心地放弃它。

我不清楚你想做什么,但我怀疑你会想看看这个类。一般来说,我认为你无法判断结果是否是“纯值”。您可以尝试查看结果是否是
FSharpFunc
(这是所有F#函数的实例),但这不会阻止调用方将函数包装到数据结构中,这是一个常见的模式。你可以找到一个概述-也许你只是想要
no struct
约束?顺便说一句:你可以尝试将这一切都包装到你自己的DSL中-但老实说,我只会在那里写一条评论,告诉用户不要使用延迟操作,因为连接将被处理是的-老实说,我并不确切知道你有什么样的问题?这就是为什么我做了两个不同的评论