SML仅在int list应为实列表时接受它
我正在尝试编写一个简单的add函数,它接受两个实列表,将匹配的索引添加到一起,并生成一个实列表,但由于某些原因,我无法让它接受实列表作为参数,而只能接受int列表SML仅在int list应为实列表时接受它,sml,Sml,我正在尝试编写一个简单的add函数,它接受两个实列表,将匹配的索引添加到一起,并生成一个实列表,但由于某些原因,我无法让它接受实列表作为参数,而只能接受int列表 fun add (nil, _) = nil | add (_, nil) = nil | add (a :: b, x :: y) = (a + x) :: add (b,y) 当我尝试运行测试输入时,val addTest=add([1.0,2.0,3.0],[0.1,0.2,0.3])它给了我: Error: oper
fun add (nil, _) = nil
| add (_, nil) = nil
| add (a :: b, x :: y) = (a + x) :: add (b,y)
当我尝试运行测试输入时,val addTest=add([1.0,2.0,3.0],[0.1,0.2,0.3])代码>它给了我:
Error: operator and operand do not agree [tycon mismatch]
operator domain: int list * int list
operand: real list * real list
我只是好奇为什么SML默认为int列表,即使“+”操作数同时用于real和int。它不应该接受“一个列表而不仅仅是int列表”吗?我发现在这种情况下,SML的默认行为是默认为int行为,因此,如果您的操作数适用于real或int,它将作为int进行计算。对于上述方法,我可以通过将元组中的参数指定为实数列表来获得所需的行为,如下所示:
fun add (nil, _) = nil
| add (_, nil) = nil
| add (a::b : real list, x::y : real list) = (a + x) :: add (b,y)
是的,+
(以及其他算术运算符)是重载的,但不是参数多态的
所以你可以做1.0+1.0
和1+1
,它们分别给出一个实数和一个整数
但是funfxy=x+y
可以推断出这两种情况,因此编译器默认为int重载
作为您自己答案的补充,您可以在代码中使用单个:real
:
fun add ([], _) = []
| add (_, []) = []
| add (x::xs, y::ys) = (x + y : real) :: add (xs, ys)
它会推断出你在其他地方也一定是真实的
您可以将此操作概括为一个名为zipWith
:
- fun zipWith f [] _ = []
| zipWith f _ [] = []
| zipWith f (x::xs) (y::ys) = f (x, y) :: zipWith f xs ys
> val ('a, 'b, 'c) zipWith = fn :
('a * 'b -> 'c) -> 'a list -> 'b list -> 'c list
- val add = zipWith (op + : real * real -> real)
> val add = fn : real list -> real list -> real list
- add [1.0, 2.0, 3.0] [4.0, 5.0, 6.0];
> val it = [5.0, 7.0, 9.0] : real list