锡兰的递归别名
Recursive aliases in Ceylon
我是 Ceylon 的新手,目前正在探索如何将一些用 TypeScript(本质上是 JavaScript)编写的现有软件移植到 Ceylon,以便它可以 运行 在 Java脚本引擎和 JVM。
有谁知道如何在锡兰编写与 Java 等同的代码:
public class Engine { ... } // Some given class definition
public interface Cont extends Callable1<Cont,Engine> {}
其中 Callable1<Y,X>
相当于锡兰 Callable<Y,[X]>
.
的 Java
想法是 Cont
的一个实例,比如命名为 c
,将是一个返回另一个 Cont
或 null
的函数。
在 Java 中,使用它的代码如下所示:
// Somewhere
public static void exec(Cont c, Engine e) {
while (c != null) c = c.call(e);
}
(这本质上是一个蹦床,其中每个调用函数 returns 继续,或 null
计算完成时。)
此外,在锡兰,我想将函数作为 Cont 的实例传递。
阅读回复后,我想出了以下解决方案,它使用了正确的结果类型(Cont?
而不是 Anything
)和 null
-测试(性能):
shared interface Cont { shared formal Cont? call(Engine e); }
// A wrapper class for an actual continuation function
class ContWrap(Cont?(Engine) fun) satisfies Cont {
shared actual Cont? call(Engine e) => fun(e);
}
shared Cont wrap(Cont?(Engine) fun) {
return ContWrap(fun);
}
// Somewhere
shared void exec(variable Cont? cont) {
while (exists cc = cont) {
cont = cc.call(this);
}
}
这很适合我,代价是每次都创建一个额外的小对象,并通过 wrap
传递函数。
这似乎可以编译,但看起来很糟糕:
class Engine() {}
Anything(Engine) foo(Engine e) {
return foo;
}
// Somewhere
variable Anything(Engine)? f = foo;
while (is Anything(Engine)(Engine) f2=f) {
f = f2(e);
}
Callable
have been discussed 的自定义实现,但目前还不可能。不过你不需要那个。
shared class Engine() {
// ...
}
shared interface Continuation {
shared formal Continuation? call(Engine engine);
}
shared void execute(variable Continuation? continuation, Engine engine) {
while ((continuation = continuation?.call(engine)) exists) {}
}
object continuation satisfies Continuation {
call(Engine engine) => null;
}
// usage
execute(continuation, Engine());
// usage in 1.2 with inline object expression
execute(object satisfies Continuation { call(Engine engine) => null; }, Engine());
因为Continuation
不(不能)满足Callable
,你不能只传入一个函数。但是在即将发布的版本中(1.2,现在可以通过 GitHub 获得),您至少可以使用 inline object expressions.
请注意,这不是地道的锡兰语,只是对您的 Java 的直接翻译。
我是 Ceylon 的新手,目前正在探索如何将一些用 TypeScript(本质上是 JavaScript)编写的现有软件移植到 Ceylon,以便它可以 运行 在 Java脚本引擎和 JVM。
有谁知道如何在锡兰编写与 Java 等同的代码:
public class Engine { ... } // Some given class definition
public interface Cont extends Callable1<Cont,Engine> {}
其中 Callable1<Y,X>
相当于锡兰 Callable<Y,[X]>
.
想法是 Cont
的一个实例,比如命名为 c
,将是一个返回另一个 Cont
或 null
的函数。
在 Java 中,使用它的代码如下所示:
// Somewhere
public static void exec(Cont c, Engine e) {
while (c != null) c = c.call(e);
}
(这本质上是一个蹦床,其中每个调用函数 returns 继续,或 null
计算完成时。)
此外,在锡兰,我想将函数作为 Cont 的实例传递。
阅读回复后,我想出了以下解决方案,它使用了正确的结果类型(Cont?
而不是 Anything
)和 null
-测试(性能):
shared interface Cont { shared formal Cont? call(Engine e); }
// A wrapper class for an actual continuation function
class ContWrap(Cont?(Engine) fun) satisfies Cont {
shared actual Cont? call(Engine e) => fun(e);
}
shared Cont wrap(Cont?(Engine) fun) {
return ContWrap(fun);
}
// Somewhere
shared void exec(variable Cont? cont) {
while (exists cc = cont) {
cont = cc.call(this);
}
}
这很适合我,代价是每次都创建一个额外的小对象,并通过 wrap
传递函数。
这似乎可以编译,但看起来很糟糕:
class Engine() {}
Anything(Engine) foo(Engine e) {
return foo;
}
// Somewhere
variable Anything(Engine)? f = foo;
while (is Anything(Engine)(Engine) f2=f) {
f = f2(e);
}
Callable
have been discussed 的自定义实现,但目前还不可能。不过你不需要那个。
shared class Engine() {
// ...
}
shared interface Continuation {
shared formal Continuation? call(Engine engine);
}
shared void execute(variable Continuation? continuation, Engine engine) {
while ((continuation = continuation?.call(engine)) exists) {}
}
object continuation satisfies Continuation {
call(Engine engine) => null;
}
// usage
execute(continuation, Engine());
// usage in 1.2 with inline object expression
execute(object satisfies Continuation { call(Engine engine) => null; }, Engine());
因为Continuation
不(不能)满足Callable
,你不能只传入一个函数。但是在即将发布的版本中(1.2,现在可以通过 GitHub 获得),您至少可以使用 inline object expressions.
请注意,这不是地道的锡兰语,只是对您的 Java 的直接翻译。