将使用 2 个序列的 Seq.map 应用于采用 2 个参数的方法

发布于 2024-11-09 17:05:08 字数 930 浏览 4 评论 0原文

我正在编写一个快速的数据库性能测试,并选择了 F#,这样我就可以获得更多练习。

我创建了一个方法 measureSelectTimes,其签名为 Guid list * Guid list -> IDb命令->时间跨度 * 时间跨度

然后,我称之为:

let runTests () =
    let sqlCeConn : IDbConnection = initSqlCe() :> IDbConnection
    let sqlServerConn : IDbConnection = initSqlServer() :> IDbConnection
    let dbsToTest = [ sqlCeConn; sqlServerConn ]
    let cmds : seq<IDbCommand> = dbsToTest |> Seq.map initSchema
    let ids : seq<Guid list * Guid list> = cmds |> Seq.map loadData
    let input = Seq.zip ids cmds
    let results = input |> Seq.map (fun i -> measureSelectTimes (fst i) (snd i))
    // ...

我已经用类型明确注释了以进行澄清。

我不知道如何在没有 lambda 的情况下调用 measureSelectTimes 。我想将 ids 部分应用到它,如下所示: ids |> Seq.mapmeasureSelectTimes 但我不知道如何处理所得到的部分应用函数,然后映射到 cmds 上。这个的语法是什么?

I'm writing a quick DB perf test, and chose F# so I can get more practice.

I've created a method, measureSelectTimes, which has the signature Guid list * Guid list -> IDbCommand -> TimeSpan * TimeSpan.

Then, I call it:

let runTests () =
    let sqlCeConn : IDbConnection = initSqlCe() :> IDbConnection
    let sqlServerConn : IDbConnection = initSqlServer() :> IDbConnection
    let dbsToTest = [ sqlCeConn; sqlServerConn ]
    let cmds : seq<IDbCommand> = dbsToTest |> Seq.map initSchema
    let ids : seq<Guid list * Guid list> = cmds |> Seq.map loadData
    let input = Seq.zip ids cmds
    let results = input |> Seq.map (fun i -> measureSelectTimes (fst i) (snd i))
    // ...

I've annotated explicitly with types to clarify.

What I can't figure out is how to call measureSelectTimes without the lambda. I'd like to partially apply the ids to it like this: ids |> Seq.map measureSelectTimes but then I don't know what to do with the resulting partially applied functions to then map onto the cmds. What's the syntax for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

对你再特殊 2024-11-16 17:05:08

您可以使用Seq.map2

Seq.map2 measureSelectTimes ids cmds

或者

(ids, cmds) ||> Seq.map2 measureSelectTimes

You can use Seq.map2:

Seq.map2 measureSelectTimes ids cmds

Or

(ids, cmds) ||> Seq.map2 measureSelectTimes
撩起发的微风 2024-11-16 17:05:08

您的 measureSelectTimes 函数将两个参数作为单独的参数,但您需要一个将它们作为元组的函数。一种选择是仅更改函数以采用元组(如果对参数进行元组化是合乎逻辑的)。

或者,您可以编写一个组合器,将带有两个参数的函数转换为带有元组的函数。这通常称为 uncurry ,它存在于某些函数式语言中:

let uncurry f (a, b) = f a b

然后你可以这样写:

input |> Seq.map (uncurry measureSelectTimes)

对于像这样的简单使用来说,这看起来没问题,但我认为在 F# 中过多使用组合器并不是一个好主意因为它使得经验不足的函数式程序员难以阅读代码。我可能会写这样的东西(因为我发现这样更具可读性):

[ for (time1, time2) in input -> measureSelectTimes time1 time2 ]

Your measureSelectTimes function takes two arguments as separate arguments, but you instead need a function that takes them as a tuple. One option is to just change the function to take a tuple (if it is logical for the arguments to be tupled).

Alternative, you can write a cobinator that turns a function taking two arguments into a function taking tuple. This is usually called uncurry and it exists in some functional language:

let uncurry f (a, b) = f a b

Then you can write:

input |> Seq.map (uncurry measureSelectTimes)

This looks okay for a simple use like this, but I think that using combinators too much in F# is not a good idea as it makes code difficult to read for less experienced functional programmers. I would probably write something like this (because I find that more readable):

[ for (time1, time2) in input -> measureSelectTimes time1 time2 ]
烂柯人 2024-11-16 17:05:08

一种方法是将 measureSelectTimes 的签名更改为

(Guid list * Guid list) * IDbCommand -> TimeSpan * TimeSpan

然后您可以将 map 调用更改为

let results = input |> Seq.map measureSelectTimes
// or
let results = Seq.map measureSelectTimes input

One approach is to change the signature of measureSelectTimes to

(Guid list * Guid list) * IDbCommand -> TimeSpan * TimeSpan

Then you can change the map call to

let results = input |> Seq.map measureSelectTimes
// or
let results = Seq.map measureSelectTimes input
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文