F#使用方程式进行查询

3
我正在处理一些需要使用f#查询来对列表求和的代码。
对于那些正在学习f#基础知识的人,这是一个很方便的链接:https://learnxinyminutes.com/docs/fsharp/ 到目前为止,我已经编写了一段代码,用于输出5个数字平方之和的语句。
到目前为止,这个代码正确地显示了每个列表的平方和为3000。'numbers'将被用于查询。
let square x = x * x
let numbers = [10.0; 20.0; 30.0; 40.0]

let sumOfSquare2 =
   [10.0; 20.0; 30.0; 40.0] 
   |> List.map square 
   |> List.sum 

printfn "Sum of square: %A" (sumOfSquare2)

let sumOfSquare = 
    List.sum ( List.map square [10.0; 20.0; 30.0; 40.0] )

printfn "Sum of square: %A" (sumOfSquare)

目前,我有些困惑如何在查询后正确使用“square”函数。

// A query expression.

let query1 =
    query {
        for number in numbers do
            select (number)           
    }
   |> square query   


printfn "Query sum of squares: %A" (query1)

那么我应该如何正确地呈现这个问题?'query'本身是有效的(在使用printfn对query进行操作时),但当尝试将square函数传输到query时,它无法编译。

3个回答

2

这将基本上是你使用 list 的相同代码,但由于查询返回一个 seq,所以请使用 Seq.map 而不是 List.map

// A query expression.
let query1 =
    query {
        for number in numbers do
            select (number)           
    }
   |> Seq.map square    


printfn "Query sum of squares: %A" (query1)

请注意,您的查询并没有进行任何转换,我认为您这样做只是作为一个示例。

你好!非常感谢。这个很好用。我只是想知道如何添加query1的值(因为这个打印语句返回每个列表值的平方)。这需要通过管道在query1表达式中实现吗? - EidahageFeroe
1
@MichaelPotts 那应该是和你最初的例子一样,只需要将列表函数替换为序列函数即可,例如用Seq.sum代替List.sum等。 - Gus

1
请注意,查询返回一个序列,您可以迭代该序列,然后执行您的操作。
例如:
// Print results of a query
query1
|> Seq.map (fun customer -> printfn "Company: %s Contact: %s" customer.CompanyName customer.ContactName)

您可以像这样使用它:

query1 |> Seq.map (fun e -> square(e)) |> Seq.sum

完整源代码。
open System

// your code goes here
let square x = x * x
let numbers = [10.0; 20.0; 30.0; 40.0]

let query1 =
    query {
        for number in numbers do
            select (number)           
    } |> Seq.map square |> Seq.sum

Console.WriteLine(sprintf "%A" query1);

试一试

要了解更多关于查询的内容,请访问https://learn.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/query-expressions


让query1 |> Seq.iter (fun e -> square(e)) |> Seq.sum结果编译错误。我真的不知道如何将其应用到我的问题上。我已经阅读了您提供的文章,但它并没有解决我遇到的问题,即将我的平方函数应用于查询结果。 - EidahageFeroe
这是我理解你的解决方案的方式。这会导致编译错误。 let query1 = query { for number in numbers do select (number)
} |> Seq.iter (fun e -> square(query)) |> Seq.sum
- EidahageFeroe
1
如果您查看Seq.iter的函数签名,您会发现它返回单元,因此通常用于其副作用(例如打印到屏幕)。确实,您需要使用Seq.map然后是Seq.sum。查询返回序列,这些序列是惰性的,因此如果要强制评估它,只需将其管道传递给数组:|> Seq.toList - s952163
1
抱歉,应该使用映射而不是迭代器...已经修复了。 - Saravanan

1
F#支持在查询中进行求和,因此您只需执行以下操作即可获得平方和的总和:
query {
    for num in numbers do
    sumBy (square num)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接