2

我是 Ceylon 的新手,目前正在探索如何将一些用 TypeScript(本质上是 JavaScript)编写的现有软件移植到 Ceylon,以便它可以在 JavaScript 引擎和 JVM 上运行。

有谁知道如何在 Ceylon 编写等效的 Java 代码:

public class Engine { ... } // Some given class definition

public interface Cont extends Callable1<Cont,Engine> {}

哪里Callable1<Y,X>是 Ceylon 的 Java 等价物Callable<Y,[X]>

这个想法是,一个实例Cont,比如说命名c,将是一个函数,要么返回另一个Cont,要么返回一个null.

在 Java 中,使用它的代码如下所示:

// Somewhere
public static void exec(Cont c, Engine e) {
  while (c != null) c = c.call(e);
}

(这本质上是一个蹦床,每个被调用的函数都返回延续,或者null当计算完成时。)

另外,在锡兰我想将函数作为 Cont 的实例传递。


阅读回复后,我提出了以下解决方案,该解决方案同时使用了正确的结果类型(Cont?而不是Anything)和null-testing(用于性能):

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.

4

2 回答 2

3

的自定义实现Callable已经讨论过,但目前还不可能。不过,你不需要那个。

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 获得)中,您至少可以使用内联对象表达式

请注意,这不是惯用的 Ceylon,只是从您的 Java 相当直接的翻译。

于 2015-02-18T21:10:04.273 回答
1

这似乎可以编译,但看起来非常可怕:

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);
}
于 2015-02-18T21:07:19.753 回答