尝试在 Rascal 中实现结果类型和 partial() 时出现类型问题

Type issues when trying to implement the Result type and partial() in Rascal

尝试在 Rascal

中实现 Result/Maybe 和 partial() 时出现类型问题

下面您会发现我尝试实现结果类型,包括函数 Bind 和 Pure(又名 return)。 一切似乎都很好,直到我把零件放在一起。

  1. 首先,IDE 在 (*) 处检测到类型问题,即使执行结果是预期的值和类型。
  2. 其次,在执行代码 (**) 时,值符合预期,即使类型不是我所期望的。
    • 结果类型是:Result[&S,&E]:Ok(Banana("banana"))
    • 我期望的类型是:结果[Banana, Undefined]: Ok(Banana("banana"))

另一方面,当我使用第二个绑定实现 (bindR2) 时,测试 (***) 失败并在调用中出现异常:partial(bindR2, functionA)(PureR(Apple("Apple" )))。 这里的错误是:

project:///src/Result.rsc|(964,10,<39,80>,<39,90>):  Expected Result[Apple,&E], but got Result[Banana,Undefined]

这表明结果值和类型是我期望的,但 Rascal 期望的是不同的类型。

我想知道我是否在这段代码中错误地使用了类型变量,或者我没有正确使用类型系统?

module Result

import Exception;

public alias Undefined  = RuntimeException;
data Result[&S, &E] = Ok(&S) | Error (&E);

// PureR (aka return)
public Result[&S, &E] PureR(&S s) = Ok(s);

// bindR. first implementation of bind,
public Result[&S, &E] bindR( ( Result[&S, &E] ( &Sin ) ) f, Result[&Sin, &E] xR) {
    switch (xR) {
        case Ok(x)    : return f(x);
        case Error(e) : return Error(e);
    }
}

// bindR2. Second implementation of bind,
public Result[&S, &E] bindR2( ( Result[&S, &E] ( &Sin ) ) f, Ok(x)    ) = f(x);
public Result[&S, &E] bindR2( ( Result[&S, &E] ( &Sin ) ) f, Error(e) ) = Error(e);

// Tests BindR
// test helpers
public data Apple  = Apple(str);
public data Banana = Banana(str);
public int add(int x, int y) = x + y; 
public Result[num, void] fb(&Success <: num x) = Ok(x*3);
public Result[Banana,  Undefined] functionA (Apple apple) = Ok(Banana("banana"));

test bool testBindResult1() = bindR(fb, Ok(3))      == Ok(9);
test bool testBindResult2() = bindR2(fb, Ok(3))     == Ok(9);
test bool testBindResult3() = bindR(fb, Error([]))  == Error([]);
test bool testBindResult4() = bindR2(fb, Error([])) == Error([]);
test bool testBindResult5() = bindR(functionA, PureR(Apple("apple")))  == Ok(Banana("banana"));
test bool testBindResult6() = bindR2(functionA, PureR(Apple("apple"))) == Ok(Banana("banana")); // (*) <-- Type checker warning

// partial application.
public (&T (&X2)) partial( (&T (&X1, &X2)) f, &X1 x1 ) = (&T)( &X2 x2 ) { return f(x1, x2); };

// Test partial on BindR and BindR2
// Test
test bool testPartialAdd() = partial(add, 3)(3) == 6;
test bool testPartialBindR() = partial(bindR, functionA)(PureR(Apple("Apple"))) == Ok(Banana("banana")); // (**) <-- Type checker warning
// ERROR: test bool testPartialBindR2() = partial(bindR2, functionA)(PureR(Apple("Apple"))) == Ok(Banana("banana")); // (***) <-- Runtime type error.

当我排列类型检查器显示的错误部分(partial(bindR, functionA) 下 ** 处的红色波浪线)时,它显示如下:

Function of type
1. ...fun
2. ...... fun &T <: value ( &X2 <: value )
3. ...........( fun &T <: value                      ( &X1 <: value,                                          &X2 <: value                      ), &X1 <: value                             )
cannot be called with argument types 
4. .............fun Result[&S <: value, &E <: value] ( fun Result[&S <: value, &E  <: value] (&Sin <: value), Result[&Sin <: value, &E <: value]), fun Result[Banana, RuntimeException](Apple)

2 是部分函数,​​其计算结果为取值为 &X2 的函数并生成类型为 &T.
的值 3 是输入的预期类型。
4 是提供的输入的类型。

而且所有类型似乎都在排队

这也说明 &X1 被提到了两次。一次使用类型变量 en 一次使用代码中提供的函数的类型。

在大多数代码中,我看到类型系统能够解析类型变量的类型,在本例中为 &S、&E 和 &Sin。 &S 应该解析为 Banana,&E 解析为 RuntimeException,&Sin 解析为 Apple。

问得好。

  • 类型检查器仍处于测试阶段,可能会产生虚假错误和警告。解释器现在将忽略它们。
  • 我怀疑 运行-time 类型确实是 Result[Banana, Undefined],你可以使用类型库模块中的 typeOf 函数检查一下。 println("<typeOf(x)>")
  • 如果这是真的,这个 {c,w} 将是一个类型实例化错误(忘记实例化一级类型参数以防高阶函数???)在抽象解释中产生( static) 类型的变量,在解释结果旁边。请将此作为问题提交?
  • 那个(假设的)错误也可以解释第二个实现的 运行 次失败,它检查意外未实例化的类型参数的子类型并在此失败。