神刀安全网

Closure-based State in F#

Being an object/functional hybrid language, F# offers the opportunity to support either a traditional object-field approach to encapsulating state, as well as the more “functional” style ofClosure-based State. As such, developers will generally prefer to store state in object/class fields, but there can still be situations where encapsulating the state away from the object as a whole can be preferable.

However, F# has some interesting language restrictions around enclosed bound variables; specifically, because F# wants to assume that all bound values are immutable by default, F# will require a slight amendment to the enclosed local state, marking it as a “reference” (using the ref keyword), before it can be used inside of a returned function:

let operation =     let state = ref 100     fun adjust ->         state := (!state) + adjust 

Thanks to F#’s “last expression in an expression block is the assumed return value” feature, making use of this feels absolutely trivial; the anonymous function receiving the single parameter adjust is assigned to the local value operation , meaning that now operation will be operating on the referenced state value, but without any sort of opportunity for any other operation or library to modify state .

When working with objects this gets trickier, since F# (like its kin C# and Visual Basic) is a strongly-typed language, and as such wants clients to have compile-time awareness of the object types they are invoking. Thus, the typical idiomatic usage for F# here will be to use Closure-based State to implement an anonymous implementation of an interface, and have the outer function declared to return an instance of such. This is trivial to do with object expressions:

type IInterface =     interface         abstract Operation: (int) -> int     end  let instance =     let state = ref 100     { new IInterface with         member x.Operation(adjust) =              state := (!state) + adjust             !state     }  let result = instance.Operation(100) printfn "%A" result

Alternatively, F# can return an instance of aDynamic Object; this is somewhat contradictory to the spirit of the F# language, since it is strongly-typed by nature, but circumstances will sometimes suggest it as useful, depending (as always) on the context.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Closure-based State in F#

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址