尝试在 Rascal 中实现结果类型和 partial() 时出现类型问题
Type issues when trying to implement the Result type and partial() in Rascal
尝试在 Rascal
中实现 Result/Maybe 和 partial() 时出现类型问题
下面您会发现我尝试实现结果类型,包括函数 Bind 和 Pure(又名 return)。
一切似乎都很好,直到我把零件放在一起。
- 首先,IDE 在 (*) 处检测到类型问题,即使执行结果是预期的值和类型。
- 其次,在执行代码 (**) 时,值符合预期,即使类型不是我所期望的。
- 结果类型是: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 是提供的输入的类型。
而且所有类型似乎都在排队
&T <: value
与 Result[&S <: value, &E <: value]
对齐
&X1 <: value
与 fun Result[&S <: value, &E <: value] (&Sin <: value)
对齐
&X2 <: value
与 Result[&Sin <: value, &E <: value]
对齐
&X1 <: value
与 fun Result[Banana, RuntimeException](Apple)
对齐
这也说明 &X1 被提到了两次。一次使用类型变量 en 一次使用代码中提供的函数的类型。
在大多数代码中,我看到类型系统能够解析类型变量的类型,在本例中为 &S、&E 和 &Sin。 &S 应该解析为 Banana,&E 解析为 RuntimeException,&Sin 解析为 Apple。
问得好。
- 类型检查器仍处于测试阶段,可能会产生虚假错误和警告。解释器现在将忽略它们。
- 我怀疑 运行-time 类型确实是
Result[Banana, Undefined]
,你可以使用类型库模块中的 typeOf
函数检查一下。 println("<typeOf(x)>")
- 如果这是真的,这个 {c,w} 将是一个类型实例化错误(忘记实例化一级类型参数以防高阶函数???)在抽象解释中产生( static) 类型的变量,在解释结果旁边。请将此作为问题提交?
- 那个(假设的)错误也可以解释第二个实现的 运行 次失败,它检查意外未实例化的类型参数的子类型并在此失败。
尝试在 Rascal
中实现 Result/Maybe 和 partial() 时出现类型问题下面您会发现我尝试实现结果类型,包括函数 Bind 和 Pure(又名 return)。 一切似乎都很好,直到我把零件放在一起。
- 首先,IDE 在 (*) 处检测到类型问题,即使执行结果是预期的值和类型。
- 其次,在执行代码 (**) 时,值符合预期,即使类型不是我所期望的。
- 结果类型是: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 是提供的输入的类型。
而且所有类型似乎都在排队
&T <: value
与Result[&S <: value, &E <: value]
对齐
&X1 <: value
与fun Result[&S <: value, &E <: value] (&Sin <: value)
对齐
&X2 <: value
与Result[&Sin <: value, &E <: value]
对齐
&X1 <: value
与fun Result[Banana, RuntimeException](Apple)
对齐
这也说明 &X1 被提到了两次。一次使用类型变量 en 一次使用代码中提供的函数的类型。
在大多数代码中,我看到类型系统能够解析类型变量的类型,在本例中为 &S、&E 和 &Sin。 &S 应该解析为 Banana,&E 解析为 RuntimeException,&Sin 解析为 Apple。
问得好。
- 类型检查器仍处于测试阶段,可能会产生虚假错误和警告。解释器现在将忽略它们。
- 我怀疑 运行-time 类型确实是
Result[Banana, Undefined]
,你可以使用类型库模块中的typeOf
函数检查一下。println("<typeOf(x)>")
- 如果这是真的,这个 {c,w} 将是一个类型实例化错误(忘记实例化一级类型参数以防高阶函数???)在抽象解释中产生( static) 类型的变量,在解释结果旁边。请将此作为问题提交?
- 那个(假设的)错误也可以解释第二个实现的 运行 次失败,它检查意外未实例化的类型参数的子类型并在此失败。