I'm trying to write a small little scripting engine for a bullet hell game and I would like to do it in F#. I wrote some C# code to conceptualize it, but I'm having trouble porting it to F#. The C# code is posted below, and I would like some help porting it to F#. I have a feeling the matching F# code will be significantly smaller. I'm open to any sort of creative solutions :)
interface IRunner
{
Result Run(int data);
}
struct Result
{
public Result(int data, IRunner next)
{
Data = data;
Next = next;
}
public int Data;
public IRunner Next;
}
class AddOne : IRunner
{
public Result Run(int data)
{
return new Result(data + 1, null);
}
}
class Idle : IRunner
{
public Result Run(int data)
{
return new Result(data, null);
}
}
class Pair : IRunner
{
IRunner _one;
IRunner _two;
public Pair(IRunner one, IRunner two)
{
_one = one;
_two = two;
}
public Result Run(int data)
{
var res = _one.Run(data);
if (res.Next != null)
return new Result(res.Data, new Pair(res.Next, _two));
return new Result(res.Data, _two);
}
}
class Repeat : IRunner
{
int _counter;
IRunner _toRun;
public Repeat(IRunner toRun, int counter)
{
_toRun = toRun;
_counter = counter;
}
public Result Run(int data)
{
var res = _toRun.Run(data);
if (_counter > 1)
{
if (res.Next != null)
return new Result(res.Data,
new Pair(res.Next,
new Repeat(_toRun, _counter - 1)));
return new Result(res.Data, new Repeat(_toRun, _counter - 1));
}
return res;
}
}
class Sequence : IRunner
{
IEnumerator<IRunner> _runner;
public Sequence(IEnumerator<IRunner> runner)
{
_runner = runner;
}
public Result Run(int data)
{
var res = _runner.Current.Run(data);
bool next = _runner.MoveNext();
if (res.Next != null)
{
return new Result(res.Data,
new Pair(res.Next, new Sequence(_runner)));
}
return new Result(res.Data, new Sequence(_runner));
}
}