gpt4 book ai didi

F#:有没有办法扩展 monad 关键字列表?

转载 作者:行者123 更新时间:2023-12-03 09:21:54 26 4
gpt4 key购买 nike

在 F# monad 中,如果你说 let! ,编译器将其转换为 Bind您在 monad 构建器上定义的成员。

现在我看到有 Query monad,如 shown here on MSDN ,你可以说:

query {
for student in db.Student do
select student
count
}

selectcount例如,将转换为 QueryBuilder 成员(member) Linq.QueryBuilder.Select Linq.QueryBuilder.Count .

我的问题是,这种关键字到成员的映射是硬连线到 F# 编译器中的,还是可扩展的?例如,我可以这样说:
FooMonadBuilder() {
bar
}

并以某种方式告诉 F# 编译器 bar映射到 FooMonadBuilder.Bar()方法?

最佳答案

在 F# 2.0(即 Visual Studio 2010)中,无法扩展关键字列表(Ramon 的扩展除外)。但是,F# 3.0 (Visual Sutdio 11) 中的查询机制是可扩展的,您可以定义自己的关键字,类似于 selectcount .

这是一个定义类似 seq 的基本示例。建筑商 reverse关键词:

type SeqBuilder() =
// Standard definition for 'for' and 'yield' in sequences
member x.For (source : seq<'T>, body : 'T -> seq<'R>) =
seq { for v in source do yield! body v }
member x.Yield item =
seq { yield item }

// Define an operation 'select' that performs projection
[<CustomOperation("select")>]
member x.Select (source : seq<'T>, [<ProjectionParameter>] f: 'T -> 'R) : seq<'R> =
Seq.map f source

// Defines an operation 'reverse' that reverses the sequence
[<CustomOperation("reverse", MaintainsVariableSpace = true)>]
member x.Expand (source : seq<'T>) =
List.ofSeq source |> List.rev

let mseq = SeqBuilder()

尚未记录其工作原理的详细信息,但 CustomOperation属性表示该操作应该被视为一种特殊的语法(您可以设置各种属性来指定它的行为方式 - MaintainsVariableSpace 意味着它不会更改序列内的值)。 Projectionparameter属性指定应将关键字后面的表达式隐式转换为函数。

现在, mseq builder 同时支持 selectreverse :
let q = mseq { for i in 1 .. 10 do
select (i + 100)
reverse }

关于F#:有没有办法扩展 monad 关键字列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9272285/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com