Gittikçe bir değer oluşturan ve birçok özel işlem içeren bir hesaplama ifadesi oluşturucu var. Ancak, standart F # dil yapılarına izin vermez ve bu desteği nasıl ekleyeceğimi bulmakta çok fazla sorun yaşıyorum.Bir değer biriktiren ve standart dil yapılarına izin veren bir hesaplama ifadesi oluşturucu nasıl yazılır?
tek başına bir örnek vermek gerekirse, burada F # listelerini oluşturur bir ölü basit ve oldukça anlamsız hesaplama deyim:
Ben sadece iyi listeleri oluşturmak için kullanabilirtype Items<'a> = Items of 'a list
type ListBuilder() =
member x.Yield(()) = Items []
[<CustomOperation("add")>]
member x.Add(Items current, item:'a) =
Items [ yield! current; yield item ]
[<CustomOperation("addMany")>]
member x.AddMany(Items current, items: seq<'a>) =
Items [ yield! current; yield! items ]
let listBuilder = ListBuilder()
let build (Items items) = items
:
let stuff =
listBuilder {
add 1
add 5
add 7
addMany [ 1..10 ]
add 42
}
|> build
Ancak bu bir derleyici hatadır:
listBuilder {
let x = 5 * 39
add x
}
// This expression was expected to have type unit, but
// here has type int.
Ve böylece şudur:
listBuilder {
for x = 1 to 50 do
add x
}
// This control construct may only be used if the computation expression builder
// defines a For method.
Bulduğum tüm belgeleri ve örnekleri okudum, ancak almadığım bir şey var. Her bir .Bind()
veya .For()
yöntem imzası Ben sadece daha fazla kafa karıştırıcı derleyici hataları neden olur deneyin. Bulunduğum örneklerin çoğu ya giderken bir değer oluşturuyor ya da normal F # dil yapılarına izin veriyor, ancak her ikisini de yapamadım.
birisi nasıl bu örneği alıp minimumda (let
bağlamaları ve for
döngüler için oluşturucudaki desteği eklemek için bana göstererek doğru yönde işaret olsaydı - çok iyi olurdu using
, while
ve try/catch
ama muhtemelen yapabiliriz Birisi beni başlatırsa, bunu anlayın) o zaman dersi minnetle benim asıl sorunuma uygulayabileceğim. Gördüğüm
Açıklama için teşekkürler! Kaybettiğim ana şey, taşınan değeri geçerli değerden ve 'ProjectionParameter' özniteliğinden çıkarmak için 'Çalıştır' kaynağı sağlamaktı. 'For' ve diğer oluşturucu yöntemleri üzerine yazılan belgeler, derleyicinin herşeyin 'birim' olmasını beklemediğinden artık çok daha mantıklı olacak. –
Bir [aşağıdaki soruyu burada yayınladım] (http://stackoverflow.com/questions/23144744/why-does-this-computation-expression-builder-expect-unit-in-my-for-loop) Yine daha az aptal olmana yardım edecek zamanın var. –
@kvb, CE'yi elinizle desugaring ediyorsanız veya * yazmıyor olsa bile genişletmeyi görmenin bir yolu var mı *? –