В С# у меня есть следующий код:
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;
}
}
Это фрагмент кода, который может выполнять определенную работу, используя предоставленный object стратегии для заполнения частей реализации. Примечание: как правило, объекты стратегии не содержат состояния; они просто полиморфно обеспечивают реализацию отдельных шагов.
Класс стратегии выглядит так:
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; }
}
Наблюдение: того же эффекта можно добиться в C# за счет использования лямбда-выражений (и полного избавления от объекта стратегии), но в этой реализации хорошо то, что расширяющие классы имеют свои Step1 и Step2. реализации вместе.
Вопрос. Какова идиоматическая реализация этой идеи в F#?
Мысли:
Я мог бы внедрить отдельные пошаговые функции в функцию работы, подобно идее в наблюдении.
Я также мог бы создать тип, который собирает две функции, и передать значение этого типа через:
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 }
Это кажется наиболее близким к тому, чего я пытаюсь достичь: он удерживает этапы реализации близко друг к другу, чтобы их можно было рассматривать как связку. Но является ли эта идея (создание типа, содержащего только значения функции) идиоматической в функциональной парадигме? Любые другие мысли?