我試圖使用計算表達式來創建類似於構建器的DSL,但是當我嘗試使用let賦值來幫助編寫內容時,出現編譯錯誤,此類賦值無法找到。這裏有一個例子:不能重新使用在計算表達式中分配的變量
type Node =
{
Key: Option<string>
Children: List<Node>
XPathFromParent: string
}
let defaultNode =
{
Key = None;
Children = [];
XPathFromParent = ".//somePath"
}
type NodeBuilder(xpath: string) =
member self.Yield(item: 'a): Node = defaultNode
member this.xpath = xpath
[<CustomOperation("xpath_from_parent")>]
member __.XPathFromParent (node, x) = {node with XPathFromParent = x}
[<CustomOperation("nodes")>]
member __.Nodes (node, x) = {node with Children = x}
[<CustomOperation("key")>]
member __.MidasMeasurementKey (node, x) = {node with Key = x}
member this.Bind(x, f) = f x
let node xpath = NodeBuilder(xpath)
let rootNode = node ".//somePath" {
let! childNodes =
[
node "somepath" {
nodes []
};
node "someOtherPath" {
nodes []
}
]
nodes childNodes // The value or constructor 'childNodes' is not defined.
}
我怎樣才能改變這種代碼,這樣我可以參考childNodes
分配給它傳遞到nodes
運營商定製?
嘿@rmunn,你已經正確地猜到了我是F#的新手:)。但是,我真的特別在尋找如何用計算表達式來實現這一點。我想要做的是創建一個構建器DSL,即使非技術人員也可以爲我的公司所面臨的業務特定問題撰寫 - 在我看來,具有計算表達式的假設版本在眼中更容易。如果僅僅是技術人員,我只會按照你明智的建議去做。 – nebffa
然後我無法爲你提供很多幫助:我可以重現你的問題,但它也在困擾着我。我可以做的最好的建議是將'printfn'語句,也就是窮人的調試器:-)撒到你的構建器中,看看它們何時(以及如果)被調用。 – rmunn
但我的另一個建議是,如果你想爲非技術人員構建DSL,計算表達式可能不如用[FParsec](http://www.quanttec.com/fparsec)滾動你自己的小語言/tutorial.html)。即使對於有經驗的開發人員來說,來自計算表達式的錯誤消息也往往有點不透明。非技術人員會發現他們不可能*弄清楚他們(說)丟掉了一個單詞(例如,,當他們應該寫入'nodes []''時寫了'']'。而如果您使用FParsec爲其提供自定義語言來編寫,則可以控制語法和錯誤消息。 – rmunn