In C# I have the following code:
public class SomeKindaWorker
{
public double Work(Strategy strat)
{
int i = 4;
// some code ...
var s = strat.Step1(i);
// some more code ...
var d = strat.Step2(s);
// yet more code ...
return d;
}
}
This is a piece of code that can do some kind of work by using a provided strategy object to fill in parts of the implementation. Note: in general the strategy objects do not contain state; they merely polymorphically provide implementations of individual steps.
The strategy class looks like this:
public abstract class Strategy
{
public abstract string Step1(int i);
public abstract double Step2(string s);
}
public class StrategyA : Strategy
{
public override string Step1(int i) { return "whatever"; }
public override double Step2(string s) { return 0.0; }
}
public class StrategyB : Strategy
{
public override string Step1(int i) { return "something else"; }
public override double Step2(string s) { return 4.5; }
}
Observation: The same effect can be achieved in C# through the use of lambdas (and getting rid of the strategy object altogether), but the nice thing about this implementation is that the extending classes have their Step1 and Step2 implementations together.
Question: What is an idiomatic implementation of this idea in F#?
Thoughts:
I could inject individual step functions into the Work function, similar to the idea in the observation.
I could also create a type that collects two functions, and pass a value of that type through:
type Strategy = { Step1: int -> string; Step2: string -> double }
let strategyA = { Step1 = (fun i -> "whatever"); Step2 = fun s -> 0.0 }
let strategyB = { Step1 = (fun i -> "something else"); Step2 = fun s -> 4.5 }
This seems like the closest match to what I'm trying to achieve: it keeps the implementing steps close together so that they may be examined as a bunch. But is this idea (creating a type to contain function values only) idiomatic in the functional paradigm? Any other thoughts?