国家monad和战略模式

时间:2013-11-27 09:47:17

标签: design-patterns f# strategy-pattern state-monad

我正在重新设计一个库,我对当前的设计模式不满意。 此问题涉及将strategy patternState monad

结合使用

我有Filter。在其基本实现中,它所做的就是采用类型'd的一些数据源并更新自身,生成自己的新更新副本。

[<AbstractClass>]
type Filter<'d, 'F> (state: 'F) =
    member val StateVariable = state with get
    abstract member Update: 'd -> Filter<'d, 'F>

我有一个ISignalGenerator,它会获取过滤器,环境数据并对其进行处理,以生成Signal类型'S

type ISignalGenerator<'d, 'F, 'S> =
    abstract member GenerateSignal: 'd -> Filter<'d,'F> -> 'S

SignalGenerator是一个策略模式对象。在SignalGenerator的实现中,库用户安装将使用和组合的函数以生成Signal

我可以将代码包装在state monad中。与一些环境变量(数据馈送)一起,状态monad将携带'Filter'作为状态。然后,SignalGenerator将通过状态monad获取状态更新(类型'dFilter的数据源)

我遇到的设计问题是我想将SignalGenerator类型与工作流程的开发分离,即我想避免将状态monad嵌套在{{1}的腹部中}。是否有功能设计模式来实现这一目标?

修改

根据Tomas的评论,我参与了一个玩具模型。 选择拥有策略类是基于将许多函数组合在一起的需要。

SignalGenerator

我想知道是否会有一个模式解决方案,其中///////////////////////////////////////////////////////////////////////////////////// // Definition of the state ///////////////////////////////////////////////////////////////////////////////////// type StateFunc<'State, 'T> = 'State -> 'T * 'State ///////////////////////////////////////////////////////////////////////////////////// // Definition of the State monad type ///////////////////////////////////////////////////////////////////////////////////// type StateMonadBuilder<'State>() = // M<'T> -> M<'T> member b.ReturnFrom a : StateFunc<'State, 'T> = a // 'T -> M<'T> member b.Return a : StateFunc<'State, 'T> = ( fun s -> a, s) // M<'T> * ('T -> M<'U>) -> M<'U> member b.Bind(p : StateFunc<_, 'T>, rest : 'T -> StateFunc<_,_>) : StateFunc<'State, 'U> = (fun s -> let a, s' = p s rest a s') // Getter for the whole state, this type signature is because it passes along the state & returns the state member b.getState : StateFunc<'State, _> = (fun s -> s, s) // Setter for the state member b.putState (s:'State) : StateFunc<'State, _> = (fun _ -> (), s) ///////////////////////////////////////////////////////////////////////////////////// // The actual example ///////////////////////////////////////////////////////////////////////////////////// let state = StateMonadBuilder<int> () // DoubleFunctOne defines standard operations that remain always the same type Strategy (functOne) = member this.DoubleFunctOne (x: int) = state { let! res = functOne x return res * 2 } // I introduce customization with the definition of this function. // Whenever I need, I will swap the function with some other let myFunctOne x = state { let someOtherFun x = x + 10 let! currState = state.getState return currState * someOtherFun x} // Here I mount the custom function on the strategy class, so the Strategy.DoubleFunctOne can produce a result // In order to do so, I need to keep the construction in the state monad let strategy1 = state { return Strategy (myFunctOne) } // Here begins the client side. The client will consume the methods provided by my strategies. // He should not be concerned by the construction of the strategies // Ok, then, let's put our work in production let test1 = (state { let! strategy = strategy1 return! strategy.DoubleFunctOne 10 }) 9 类可以使用已挂载的函数而不将状态monad嵌套在其腹部。换句话说,有没有办法推迟Strategy的定义,而不会在类型推断中遇到麻烦?

我对函数式编程和F#相对较新。如果我的问题有意义,请告诉我!感谢。

0 个答案:

没有答案