Functional programming 为什么在sml中会出现奇怪的数据类型?(?.X!仪器)
生成时返回一个错误:Functional programming 为什么在sml中会出现奇怪的数据类型?(?.X!仪器),functional-programming,sml,Functional Programming,Sml,生成时返回一个错误: datatype 'a instr = Put of 'a|Get|Restore; fun makeCell (n:int):('a instr->unit)= let val stack = ref [] in (fn (instruction:'a instr)=> case instruction of Put (x) => ((stack := x :: !stack)) |Get =>
datatype 'a instr = Put of 'a|Get|Restore;
fun makeCell (n:int):('a instr->unit)=
let val stack = ref [] in
(fn (instruction:'a instr)=>
case instruction of
Put (x) => ((stack := x :: !stack))
|Get => stack := []
|Restore => (stack := []))
end;
val alice = makeCell 0;
alice (Put (3));
alice (Put 3);
alice (Get);
alice (Get);
我应该如何解决此问题?我尝试过不同的方法,但没有一种有效。当违反值限制时,会创建像
?.X1
这样的类型
您对alice
的定义创建了冲突,因为它将alice
定义为值以外的内容。(您的定义是一个函数应用程序)。因此,您的alice
不能完全多态
这里有一个更接近的定义:
val alice = fn : ?.X1 instr -> unit
/usr/local/smlnj/bin/sml: Fatal error -- Uncaught exception Error with 0
raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
/Users/Carl/Desktop/assignment 4.sml:113.1-113.16 Error: operator and operand don't agree [literal]
operator domain: ?.X1 instr
operand: int instr
in expression:
alice (Put 3)
这种对定义的修改称为eta扩展
不幸的是,这个定义为每个调用创建了一个新的单元格。(但是,您当前的定义不允许观察到这一点。)
下面是一个适用于测试代码并使用单个单元格的定义:
fun alice x = (makeCell 0) x
当只使用单个ref单元时,
alice
完全多态是没有意义的。单个单元格只能包含一种类型的值。当违反值限制时,会创建类似?.X1
的类型
您对alice
的定义创建了冲突,因为它将alice
定义为值以外的内容。(您的定义是一个函数应用程序)。因此,您的alice
不能完全多态
这里有一个更接近的定义:
val alice = fn : ?.X1 instr -> unit
/usr/local/smlnj/bin/sml: Fatal error -- Uncaught exception Error with 0
raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
/Users/Carl/Desktop/assignment 4.sml:113.1-113.16 Error: operator and operand don't agree [literal]
operator domain: ?.X1 instr
operand: int instr
in expression:
alice (Put 3)
这种对定义的修改称为eta扩展
不幸的是,这个定义为每个调用创建了一个新的单元格。(但是,您当前的定义不允许观察到这一点。)
下面是一个适用于测试代码并使用单个单元格的定义:
fun alice x = (makeCell 0) x
当只使用单个ref单元时,
alice
完全多态是没有意义的。单个单元格只能包含一种类型的值。当违反值限制时,会创建类似?.X1
的类型
您对alice
的定义创建了冲突,因为它将alice
定义为值以外的内容。(您的定义是一个函数应用程序)。因此,您的alice
不能完全多态
这里有一个更接近的定义:
val alice = fn : ?.X1 instr -> unit
/usr/local/smlnj/bin/sml: Fatal error -- Uncaught exception Error with 0
raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
/Users/Carl/Desktop/assignment 4.sml:113.1-113.16 Error: operator and operand don't agree [literal]
operator domain: ?.X1 instr
operand: int instr
in expression:
alice (Put 3)
这种对定义的修改称为eta扩展
不幸的是,这个定义为每个调用创建了一个新的单元格。(但是,您当前的定义不允许观察到这一点。)
下面是一个适用于测试代码并使用单个单元格的定义:
fun alice x = (makeCell 0) x
当只使用单个ref单元时,
alice
完全多态是没有意义的。单个单元格只能包含一种类型的值。当违反值限制时,会创建类似?.X1
的类型
您对alice
的定义创建了冲突,因为它将alice
定义为值以外的内容。(您的定义是一个函数应用程序)。因此,您的alice
不能完全多态
这里有一个更接近的定义:
val alice = fn : ?.X1 instr -> unit
/usr/local/smlnj/bin/sml: Fatal error -- Uncaught exception Error with 0
raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
/Users/Carl/Desktop/assignment 4.sml:113.1-113.16 Error: operator and operand don't agree [literal]
operator domain: ?.X1 instr
operand: int instr
in expression:
alice (Put 3)
这种对定义的修改称为eta扩展
不幸的是,这个定义为每个调用创建了一个新的单元格。(但是,您当前的定义不允许观察到这一点。)
下面是一个适用于测试代码并使用单个单元格的定义:
fun alice x = (makeCell 0) x
当只使用单个ref单元时,
alice
完全多态是没有意义的。一个单元格只能包含一种类型的值。好的,它可以工作,我应该如何写“Get”和“Restore”以便在这种情况下弹出一个单元?您的Get
和Restore
已经返回()
。事实上,这似乎是错误的。在我看来,您似乎希望Get
不要返回()
。但是您受到makeCell
类型的限制。也许您希望有一组不同类型的函数,而不是将所有操作捆绑到一个函数中。或者你可以有一个选项作为你的返回类型。好的,它可以工作,我应该如何写“Get”和“Restore”以便在这种情况下弹出一个单元?你的Get
和Restore
已经返回()
。事实上,这似乎是错误的。在我看来,您似乎希望Get
不要返回()
。但是您受到makeCell
类型的限制。也许您希望有一组不同类型的函数,而不是将所有操作捆绑到一个函数中。或者你可以有一个选项作为你的返回类型。好的,它可以工作,我应该如何写“Get”和“Restore”以便在这种情况下弹出一个单元?你的Get
和Restore
已经返回()
。事实上,这似乎是错误的。在我看来,您似乎希望Get
不要返回()
。但是您受到makeCell
类型的限制。也许您希望有一组不同类型的函数,而不是将所有操作捆绑到一个函数中。或者你可以有一个选项作为你的返回类型。好的,它可以工作,我应该如何写“Get”和“Restore”以便在这种情况下弹出一个单元?你的Get
和Restore
已经返回()
。事实上,这似乎是错误的。在我看来,您似乎希望Get
不要返回()
。但是您受到makeCell
类型的限制。也许您希望有一组不同类型的函数,而不是将所有操作捆绑到一个函数中。或者您可以使用”选项
作为返回类型。