此问题与this question
有关我有一个州monad。对象提供OOD strategy pattern中的update
函数。
我有一个简单的玩具示例:
/////////////////////////////////////////////////////////////////////////////////////
// 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)
let runState f init = f init
/////////////////////////////////////////////////////////////////////////////////////
// STRATEGY PATTERN
/////////////////////////////////////////////////////////////////////////////////////
let state = StateMonadBuilder<int> ()
// DoubleFunctOne defines standard operations that remain always the same
type Strategy (aFunction) =
member this.Update (x: int) = state {
let! currState = state.getState
let processedx = aFunction x
do! state.putState (currState + x) }
// Create a function that customizes the strategy
let myFunction x =
2 * x
// Customize the strategy with the desired function:
let strategy = Strategy (myFunction)
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Update recursively
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// ?? How to run update recursively ??
let result initialCondition =
initialCondition
|> (for i = 10 to 100 do
yield state { do! strategy.Update i } )
我的目标是应用初始条件,获取数据并递归(在for
或while
循环内,甚至在某些功能操作中)strategy
提供的功能。与monad合作,我不知道该怎么做。
谢谢。
计算表达式
受@kvb回答的启发,我在计算表达式中添加了for
方法。
// Loops through seqnc of numbers that constitute an input to func
member b.For (seqnc:_ List, func) =
seqnc
|> List.map (fun item -> func item)
|> List.reduce (fun acc item ->
(fun s ->
let _, s' = acc s
item s' ) )
我进行了一些测试,我觉得这个测试有效。 感谢。
答案 0 :(得分:1)
这样的东西?
let result initialCondition =
let rec loop = function
| 101 -> state { return () }
| i ->
state {
do! strategy.Update i
do! loop (i+1)
}
initialCondition
|> runState (loop 10)
或者,在构建器上定义For
成员,并以更加强制的方式编写它:
let result initialCondition =
let f = state {
for i in 10 to 100 do
do! strategy.Update i
}
initialCondition
|> runState f
另请注意,您对Strategy.Update
的定义可能存在错误:processedx
已绑定但尚未使用。