gpt4 book ai didi

c# - F#:需要帮助将 C# 转换为 F#

转载 作者:太空狗 更新时间:2023-10-30 00:02:21 26 4
gpt4 key购买 nike

我正在尝试为子弹 hell 游戏编写一个小型脚本引擎,我想在 F# 中完成。我写了一些 C# 代码来概念化它,但我在将它移植到 F# 时遇到了问题。 C# 代码发布在下面,我需要一些帮助将它移植到 F#。我有一种感觉,匹配的 F# 代码会小得多。我愿意接受任何类型的创造性解决方案 :)

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));
}
}

最佳答案

这里有一些几乎是相同解决方案策略的直接翻译。

也就是说,我认为可能有更好/更简单的表示选择,我仍在考虑中。

type Runner = int -> Result
and Result = Result of int * option<Runner>

let AddOne = fun x -> Result(x+1, None)

let Idle = fun x -> Result(x, None)

let rec Pair(r1,r2) = fun x ->
match r1 x with
| Result(data,None) -> Result(data, Some(r2))
| Result(data,Some(next)) -> Result(data,Some(Pair(next,r2)))

let rec Repeat r n = fun x ->
if n = 0 then r x else
match r x with
| Result(data,None) -> Result(data, Some(Repeat r (n-1)))
| Result(data,Some(next)) -> Result(data, Some(Pair(next, Repeat r (n-1))))

编辑

这是另一种更精致的方法...我仍在尝试查看是否有一种在“列表”中工作的好方法,因为结果似乎与 cons 单元同构...

type Runner = Runner of (int -> int * option<Runner>)

let AddOne = Runner(fun x -> x+1, None)

let Idle = Runner(fun x -> x, None)

let rec Pair(Runner(r1),R2) = Runner(fun x ->
match r1 x with
| data,None -> data, Some(R2)
| data,Some(next) -> data, Some(Pair(next,R2)))

let rec Repeat (Runner(r) as R) n = Runner(fun x ->
if n = 0 then r x else
match r x with
| data,None -> data, Some(Repeat R (n-1))
| data,Some(next) -> data, Some(Pair(next, Repeat R (n-1))))

编辑

还有一个版本,它使用列表,但现在我觉得这里有什么奇怪的......

type Runner = Runner of (int -> int * list<Runner>)

let AddOne = Runner(fun x -> x+1, [])

let Idle = Runner(fun x -> x, [])

let rec Pair(Runner(r1),R2) = Runner(fun x ->
match r1 x with
| data,xs -> data, xs @ [R2]) // inefficient

let rec Repeat (Runner(r) as R) n = Runner(fun x ->
if n = 0 then r x else
match r x with
| data,xs -> data, xs @ List.init (n-1) (fun _ -> R)) // inefficient

它几乎就像一个“ Action 队列”,一个 int->int 函数列表。但是每个人都可以产生一些在他之后立即运行的“后缀 Action ”(但在可能队列中的剩余工作之前),并且试图用纯功能数据结构维护顺序可能效率低下(没有正确的树/手头的队列库)。知道这将如何使用/消费会很有趣,因为也许那里的一个小变化可能会允许完全不同的策略。

关于c# - F#:需要帮助将 C# 转换为 F#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1942744/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com