I'm currently learning F# and hitting a few stumbling blocks; I think a lot of it is learning to think functionally.
One of the things I'm learning at the moment are computation expressions, and I want to be able to define a computation expression that handles some tracking state, e.g:
let myOptions = optionListBuilder {
let! opt1 = {name="a";value=10}
let! opt2 = {name="b";value=12}
}
I want to be able to have it so that myOptions
is a Option<'T> list
, so each let!
bind operation effectively causes the builder to "track" the defined options as it goes along.
I don't want to have to do it using mutable state - e.g. having a list maintained by the builder and updated with each bind
call.
Is there some way of having it so that this is possible?
Update: The resultant Option<'T> list
type is just representative, in reality I'll likely have an OptionGroup<'T>
type to contain a list as well as some additional information - so as Daniel mentioned below, I could use a list comprehension for a simple list.
I wrote a string builder computation expression here.
Noticed the underlying type is immutable (the contained
StringBuilder
is mutable, but it doesn't have to be). Instead of updating the existing data, each yield combines the current state and the incoming input resulting in a new instance ofStringBuilderUnion
You could do this with an F# list since adding an element to the head of the list is merely the construction of a new value rather than mutating the existing values.Using the
StringBuilderCE
looks like this:Noticed the
yield
instead oflet!
since I don't actually want to use the value inside the computation expression.