下面您会发现我尝试实现Result类型,包括Bind和Pure(aka return)函数。 在我将各个部分放在一起之前,一切似乎都很好。
另一方面,当我使用第二个绑定实现(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
的函数,en产生类型为&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被提及两次。一次使用类型变量,一次在代码中提供函数的类型。
在大多数代码中,我看到类型系统能够解析类型变量的类型,在这种情况下为&S,&E和&Sin。 &S应该解析为Banana,&E应该解析为RuntimeException,而&Sin应该解析为Apple。
答案 0 :(得分:0)
很好的问题。
Result[Banana, Undefined]
,您可以使用类型库模块中的typeOf
函数进行检查。 println("<typeOf(x)>")