или как это делается?
config {
cpu {
min 0.5
max 0.5
}
ram (GB 2.5)
}
Да, билдер, такой же как config, с двумя кастоиными операциями
А как он значение в config builder передает?
Да проще код скинуть, да
type CpuBuilder() = member _.Yield _ = Config() [<CustomOperation("min")>] member _.SetMin(config: Config, value: double) = config.["cpu.min"] <- string value config [<CustomOperation("max")>] member _.SetMax(config: Config, value: double) = config.["cpu.max"] <- string value config когда ты открываешь CPU билдер, он создаёт новый конфиг и заполняет его у себя Когда ты выходишь из CPU билдера в билдер выше вызывается Combine member _.Combine(mainConfig: Config, subConfig: Config) = for KeyValue(key, value) in subConfig do mainConfig.[key] <- value mainConfig
type ConfigBuilder() = member _.Zero() = Config() member this.Yield (_: unit)= this.Zero() member this.Yield x = x member _.Delay f = f() member _.Combine(mainConfig: Config, subConfig: Config) = for KeyValue(key, value) in subConfig do mainConfig.[key] <- value mainConfig [<CustomOperation("ram")>] member _.SetRam(state: Config, size: Bytes) = state.["ram"] <- string size state member _.Run x = JsonConvert.SerializeObject x @vilinski вот полный пример
Почему, кстати, почти все определяют метод Yield(_), хотя можно, и даже капельку безопаснее будет определить Yield(()) ?
Хотя как это работает я до сих пор не понимаю
Кажется, про это даже оговорка на докладе была. Ты правильно говоришь.
Обсуждают сегодня