Я хочу создать DSL, где 2 (foo
и bar
) функции могут вызываться последовательно, так чтоКак создать типизированный DSL для чередования вызовов функций
initialize()
|> foo 10
|> bar "A"
|> foo 20
|> bar "B"
|> transform
это работает довольно совершенный путь определения
type FooResult = FooResult
type BarResult = BarResult
let foo param (result_type:BarResult, result) = (FooResult, transform param result)
let bar param (result_type:FooResult, result) = (BarResult, transform param result)
однако теперь я хочу также позволить, что мультипликатор bar
вызовы могут выполняться последовательно, однако foo
s все еще должны вызываться только один раз
initialize()
|> foo 10
|> bar "A"
//OK
|> bar "B"
|> transform
initialize()
|> foo 10
|> bar "A"
|> foo 20
//should yield an compile error
|> foo 30
|> bar "B"
|> transform
В C# я могу перегрузить bar
, чтобы принять BarResult или FooResult, но это не работает для F #. По крайней мере, не легко. Я также пытался создать несколько Дискриминационных Союзов, но я действительно не могу опустить голову.
вау! Должен признаться, я не думал с точки зрения интерфейсов, но даже если бы я это сделал, я бы точно не нашел такого решения. Считаете ли вы, что решение с дискриминационными союзами также возможно? – robkuz
Я не уверен, что DUs будут работать - основной трюк здесь заключается в использовании отношения наследования между интерфейсами (где два разных типа совместимы). Я полагаю, что «inline» и перегрузка могут быть альтернативой. –
Просто еще один вопрос. В чем смысл хеша в «MarkedValue <#IBarInput, _>'? – robkuz