国家monad和战略模式

NoI*_*his 7 f# design-patterns strategy-pattern state-monad

我正在重新设计一个库,我对目前的设计模式不满意.这个问题涉及战略模式与州Monad一起使用

我有一个Filter.在它的基本实现中,它所做的就是获取一些类型的数据源'd并更新自身,生成一个新的自身更新副本.

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

我有一个ISignalGenerator,它采用过滤器,环境数据并处理它以生成一种Signal类型'S.

type ISignalGenerator<'d, 'F, 'S> =
    abstract member GenerateSignal: 'd -> Filter<'d,'F> -> 'S
Run Code Online (Sandbox Code Playgroud)

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

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

我的设计问题是我想将SignalGenerator类型从工作流程的开发中分离出来,即我想避免将状态monad嵌套在其中SignalGenerator.是否有功能设计模式来实现这一目标?

编辑

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

/////////////////////////////////////////////////////////////////////////////////////
// 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
Run Code Online (Sandbox Code Playgroud)

我想知道是否会有一个模式解决方案,Strategy类可以使用已安装的函数而不将状态monad嵌套在其腹部.换句话说,是否有一种方法可以推迟定义let state = StateMonadBuilder<int> (),而不会在类型推断中遇到头痛?

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