Enhancing the F# developer experience with MongoDB
This is a guest post by Max Hirschhorn,who is currently an intern at MongoDB. About the F# programming language F# is a multi-paradigm language built on the .NET framework. It isfunctional-first and prefers immutability, but also supportso
This is a guest post by Max Hirschhorn, who is currently an intern at MongoDB.
About the F# programming language
F# is a multi-paradigm language built on the .NET framework. It is functional-first and prefers immutability, but also supports object-oriented and imperative programming styles.
Also, F# is a statically-typed language with a type inference system. It has a syntax similar to Ocaml, and draws upon ideas from other functional programming languages such as Erlang and Haskell.
Using the existing .NET driver
The existing .NET driver is compatible with F#, but is not necessarily written in a way that is idiomatic to use from F#.
Part of the reason behind this is that everything in F# is explicit. For example, consider the following example interface and implementing class.
[] type I = abstract Foo : unit -> string type C() = interface I with member __.Foo () = "bar" // example usage let c = C() (c :> I).Foo()
So in order to use any of the interface members, the class must be
upcasted using
the :>
operator. Note that this cast is still checked at compile-time.
In a similar vein, C# supports implicit
operators,
which the BSON library uses for converting between a primitive value
and its BsonValue
equivalent, e.g.
new BsonDocument { { "price", 1.99 }, { "$or", new BsonDocument { { "qty", new BsonDocument { { "$lt", 20 } } }, { "sale", true } } } };
whereas F# does not. This requires the developer to explicitly
construct the appropriate type of BsonValue
, e.g.
BsonDocument([ BsonElement("price", BsonDouble(1.99)) BsonElement("$or", BsonArray([ BsonDocument("qty", BsonDocument("$lt", BsonInt32(20))) BsonDocument("sale", BsonBoolean(true)) ])) ])
with the query builder, we can hide the construction of BsonDocument
instances, e.g.
Query.And([ Query.EQ("price", BsonDouble(1.99)) Query.OR([ Query.LT("qty", BsonInt32(20)) Query.EQ("sale", BsonBoolean(true)) ]) ])
It is worth noting that the need to construct the BsonValue
instances
is completely avoided when using a typed QueryBuilder
.
type Item = { Price : float Quantity : int Sale : bool } let query = QueryBuilder() query.And([ query.EQ((fun item -> item.Price), 1.99) query.Or([ query.LT((fun item -> item.Quantity), 20) query.EQ((fun item -> item.Sale), true) ]) ])
What we are looking for is a solution that matches the brevity of F# code, offers type-safety if desired, and is easy to use from the language.
New features
The main focus of this project is to make writing queries against MongoDB as natural from the F# language as possible.
bson
quotations
We strive to make writing predicates as natural as possible by reusing as many of the existing operators as possible.
A taste
Consider the following query
{ price: 1.99, $or: [ { qty: { $lt: 20 } }, { sale: true } ] }
we could express this with a code quotation
bson x?price = 1.99 && (x?qty
or with type safety
bson x.Price = 1.99 && (x.Quantity
Breaking it down
The quotations are not actually executed, but instead are presented
as an abstract syntax tree (AST), from which an equivalent
BsonDocument
instance is constructed.
The ?
operator
The ?
operator is defined to allow for an unchecked comparison. The
F# language supports the ability to do a dynamic lookup (get) and
assignment (set) via the ?
and ? operators respectively, but does
not actually provide a implementation.
So, the F# driver defines the ?
operator as the value associated with
a field in a document casted to a fresh generic type.
// type signature: BsonDocument -> string -> 'a let (?) (doc : BsonDocument) (field : string) = unbox doc.[field]
and similarly defines the ? operator as the coerced assignment of a
generically typed value to the associated field in the document.
// type signature: BsonDocument -> string -> 'a -> unit let (? ignore
Queries
Unchecked expressions have the type signature
Expr<bsondocument> bool></bsondocument>
.
// $mod bson x?qty % 4 = 0 @>
Checked expressions have the type signature Expr bool>
.
// $mod bson x.Quantity % 4 = 0 @>
Updates
Unchecked expressions have the type signature
Expr<bsondocument> unit list></bsondocument>
. The reason for the list
in the
return type is to perform multiple update operations.
// $set bson [ x?qty // $inc bson [ x?qty
Mmm… sugar
A keen observer would notice that (+) 1
is not an int
, but actually
a function int -> int
. We are abusing the fact that type safety is
not enforced here by assigning the quantity field of the document to a
lambda expression, that takes a single parameter of the current value.
Note that
// $inc bson [ x?qty
is also valid.
Checked expressions either have the type signature
Expr unit list>
or Expr 'DocType>
,
depending on whether the document type has mutable fields (only matters
for record types).
// $set bson [ x.Quantity // $inc bson [ x.Quantity
mongo
expressions
Uses the monadic structure (computation expression) to define a pipeline of operations that are executed on each document in the collection.
Queries
let collection : IMongoCollection = ... mongo { for x in collection do where (x?price = 1.99 && (x?qty <p>or with a typed collection</p> <pre class="brush:php;toolbar:false"> let collection : IMongoCollection = ... mongo { for x in collection do where (x.price = 1.99 && (x.qty <h5 id="Updates">Updates</h5> <pre class="brush:php;toolbar:false"> let collection : IMongoCollection = ... mongo { for x in collection do update set x?price 0.99 inc x?qty 1 }
or with a typed collection
let collection : IMongoCollection = ... mongo { for x in collection do update set x.Price 0.99 inc x.Quantity 1 }
Serialization of F# data types
Now supports
- record types
- option types
- discriminated unions
Conclusion
Resources
The source code is available at GitHub. We absolutely encourage you to experiment with it and provide us feedback on the API, design, and implementation. Bug reports and suggestions for improvements are welcomed, as are pull requests.
Disclaimer. The API and implementation are currently subject to change at any time. You must not use this driver in production, as it is still under development and is in no way supported by MongoDB, Inc.
Acknowledgments
Many thanks to the guidance from the F# community on Twitter, and my mentors: Sridhar Nanjundeswaran, Craig Wilson, and Robert Stam. Also, a special thanks to Stacy Ferranti and Ian Whalen for overseeing the internship program.
原文地址:Enhancing the F# developer experience with MongoDB, 感谢原作者分享。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Machine Power Report 編集者: Wu Xin 国内版の人型ロボット + 大型模型チームは、衣服を折りたたむなどの複雑で柔軟な素材の操作タスクを初めて完了しました。 OpenAIのマルチモーダル大規模モデルを統合したFigure01の公開により、国内同業者の関連動向が注目を集めている。つい昨日、中国の「ヒューマノイドロボットのナンバーワン株」であるUBTECHは、Baidu Wenxinの大型モデルと深く統合されたヒューマノイドロボットWalkerSの最初のデモを公開し、いくつかの興味深い新機能を示した。 Baidu Wenxin の大規模モデル機能の恩恵を受けた WalkerS は次のようになります。 Figure01 と同様に、WalkerS は動き回るのではなく、机の後ろに立って一連のタスクを完了します。人間の命令に従って服をたたむことができる

THE とは何ですか? THE (Tokenized Healthcare Ecosystem) は、ブロックチェーン技術を使用してヘルスケア業界のイノベーションと改革に焦点を当てたデジタル通貨です。 THE コインの使命は、ブロックチェーン技術を使用して医療業界の効率と透明性を向上させ、患者、医療スタッフ、製薬会社、医療機関を含むすべての関係者間のより効率的な協力を促進することです。 THE Coin の価値と特徴 まず第一に、THE Coin はデジタル通貨として、分散化、高セキュリティ、透明性のある取引などのブロックチェーンの利点を備えており、参加者はこのシステムを信頼して利用することができます。第二に、THE コインの独自性は、ブロックチェーン技術を使用して従来の医療システムを変革し、改善するために医療および健康産業に焦点を当てていることです。

TheSandbox 通貨の最新価格を確認する方法 TheSandbox は、イーサリアム ブロックチェーン上に構築された分散型ゲーム プラットフォームで、ネイティブ トークン SAND を使用して土地、資産、ゲーム体験を購入できます。 SAND の最新価格を確認する手順は次のとおりです。 信頼できる価格確認 Web サイトまたはアプリを選択してください。一般的に使用される価格クエリ Web サイトには次のものがあります。 CoinMarketCap: https://coinmarketcap.com/Coindesk: https://www.coindesk.com/Binance: https://www.binance.com/ Web サイトまたはアプリ SAND で検索します。サンドを見る

TheGraphコインの最新価格を確認するにはどうすればよいですか? TheGraph は、ブロックチェーン データの効率的なインデックス作成とクエリ サービスを提供するように設計された分散型プロトコルです。このプロトコルは、開発者が分散型アプリケーション (dApp) を簡単に構築および起動できるようにし、これらのアプリケーションにブロックチェーン データへの便利なアクセスを提供するように設計されています。 TheGraph Coin (GRT) の最新価格を確認するには、次の手順に従います。 信頼できる価格確認 Web サイトまたはアプリを選択します。一般的に使用される価格クエリ Web サイトには次のものがあります。 CoinMarketCap: https://coinmarketcap.com/Coindesk: https://www.coind

サムスンは今年下半期に新世代のGalaxy Z FoldとFlip 6シリーズの折りたたみ画面スマートフォンを発売する予定だ。最近、韓国メディア TheElec と「時事週刊 e」がこれら 2 つの新製品の詳細を明らかにしました。 Samsung Galazy Z Fold6の写真が流出。 TheElecによると、サムスン電子のサプライチェーンメーカーは5月上旬にGalaxy Z Fold6とFlip 6関連部品の生産を開始する予定だが、対照的にGalaxy Z Fold5とFlip 5用の部品の生産は5月上旬に開始されたという。去年の5月半分。これは、Galaxy Zシリーズの標準版の今年の発売スケジュールが昨年より2~3週間ほど早いことを意味する。行く

Microsoft は最近、DeveloperProxy というコマンド ライン ツールをリリースしました。これはプレビュー バージョン 0.9 に更新されました。このソフトウェアを使用すると、HTTP API を呼び出すソフトウェアの動作をテストして、開発者がユーザーに過剰な権限を要求することを回避し、ソフトウェアの過剰認証を防ぐことができます。 . . DeveloperProxy ツールは、アプリケーションによって発行された一連の Microsoft Graph API 要求をキャプチャし、アプリケーションが呼び出す必要がある API 呼び出しの数を自動的に検出できます。 Microsoftは、これらの権限比較はローカルで実行されるため、ユーザーデータが外部にアップロードされることはないと述べた。アプリケーションが実際に必要とする以上の権限を持っていることをツールが検出すると、開発者に関連する警告が発行されます。

最近、ロジクールが今年上半期に作成したエンタープライズ デスクトップ構成のホワイト ペーパーを読みました。エンタープライズ レベルのデスクトップ周辺機器に関する知識と購入ロジックから、多くのインスピレーションが得られました。これらの新鮮な視点の多くは、中関村の古くからのファンと共有するのに非常に適しています。ロジクール ホワイト ペーパー: デスクトップ周辺機器の購入に関する新しい考え方 デスクトップ周辺機器分野のリーダーとして、ロジクールのブランド力と技術革新は誰の目にも明らかです。ホワイト ペーパーのリリース時期の重要性 ロジクールのホワイト ペーパーのリリース時期は、企業のオフィス モデルの変革と一致しています。ハイブリッド オフィス モデルの人気は、雇用主のブランディングと人材の魅力に新たな課題をもたらしています。デスクトップ周辺機器の購入における新しいトレンド 以前のデスクトップ周辺機器の購入基準は単純すぎた可能性があります。従業員の立場が異なれば、キーボード、マウス、ヘッドセット、カメラに対するニーズも大きく異なります。ロジクール ホワイト ペーパーの視点 ロジクール ホワイト

TheGraph Coin 時価総額を確認する方法 TheGraph は、開発者がブロックチェーン データのインデックスを作成し、クエリを実行できるように設計された分散型プロトコルです。そのトークン GRT は、ネットワーク料金の支払いとノード オペレーターへの報酬に使用されます。 TheGraph 通貨の市場価値を確認する方法: 信頼できる Web サイトまたはプラットフォームを選択する: CoinMarketCap、CoinGecko、Feixiaohao など、仮想通貨の市場価値情報を提供する Web サイトやプラットフォームが複数あります。正確な情報を確実に入手するには、信頼できる Web サイトまたはプラットフォームを選択することが重要です。 TheGraph を検索する: Web サイトまたはプラットフォームで GRT または TheGraph を検索します。時価総額の表示: TheGraph の時価総額は、検索結果によく表示されます。ヒント: 時価総額
