运算符和操作数don';t同意[tycon失配]-sml假设列表类型错误

运算符和操作数don';t同意[tycon失配]-sml假设列表类型错误,sml,type-mismatch,Sml,Type Mismatch,我有一个非常简单的代码,可以将一个元组列表(int*string)转换为两个列表,一个int列表和一个字符串列表-基本上是将一个元组列表转换为一个列表元组 fun unzip_single_int[] : int list = [] | unzip_single_int(x::xs) : int list = x :: unzip_single_int(xs) fun unzip_single_string[] : string list = [] | unzip_si

我有一个非常简单的代码,可以将一个元组列表(int*string)转换为两个列表,一个int列表和一个字符串列表-基本上是将一个元组列表转换为一个列表元组

fun unzip_single_int[] : int list = []
|   unzip_single_int(x::xs) : int list =
    x :: unzip_single_int(xs)   


fun unzip_single_string[] : string list = []
|   unzip_single_string(x::xs) : string list =
    x :: unzip_single_string(xs)    


fun unzip[] : (int list * string list) = ([], [])
|   unzip([twopls]) : (int list * string list) =
    let
        val x : int list =  unzip_single_int(twopls);
        val y : string list = unzip_single_string(twopls); (* this is line 28 btw *)
    in
        (x, y)
    end
错误是:

zip.sml:28.7-28.52 Error: operator and operand don't agree [tycon mismatch]
  operator domain: string list
  operand:         int list
  in expression:
    unzip_single_int twopls
出于某种原因,编译器认为val y:string list=unzip_single_string(twopls)指的是int列表

有趣的是,当我切换这两个选项时,当我改变时:

val x : int list =  unzip_single_int(twopls);
val y : string list = unzip_single_string(twopls);

错误也会切换:

zip.sml:28.7-28.47 Error: operator and operand don't agree [tycon mismatch]
  operator domain: int list
  operand:         string list
  in expression:
    unzip_single_int twopls
出于某种原因,无论第二个调用是什么,它都会假定它是上一个调用的类型。为什么要这样做?我如何克服这个问题?我在另外两个函数定义中非常清楚地指出,它们分别是int列表和string列表,那么为什么SML认为我在将它明确定义为int列表时发送了一个string列表呢


谢谢

你的问题的答案是类型推断。您没有为
twopls
指定任何类型,也没有为
unzip
指定参数类型,在为
x
进行值声明时,您正在调用
unzip\u single\u int(twopls)
。因此,SML推断
twopls
是一个
int list
,因为函数
unzip\u single\u int
的类型是
int list->int list
,这意味着它将
int list
作为输入并返回
int list

SML推断出
twopls
是一个
int列表
后,您试图调用
unzip\u single\u string(twopls)
。但是,函数
unzip_single_string
的类型是
string list->string list
,因此它需要一个
string list
表达式作为输入。但是现在
twopls
是一个
int列表
,因此您会得到一个类型错误


但是,您的函数定义不会改变列表的任何内容,它们返回完全相同的列表,我猜您希望它们返回元组中的第一个或第二个元素,因此您应该添加它。您的
解压
函数应该具有类型
(int*string)list->int list*string list
。因此,尝试对列表中的
int*字符串
元素进行模式匹配。通常情况下,您会对一个列表进行模式匹配,如
x::xs
,但如果您知道元素是元组,并且希望访问它们,则可以对它们进行模式匹配,如
(num,str)::xs
,其中
num
int
变量,
str
字符串
变量。你应该能搞清剩下的。祝你好运

很高兴他们在错误消息中使用了非常有用的术语“tycon”!
zip.sml:28.7-28.47 Error: operator and operand don't agree [tycon mismatch]
  operator domain: int list
  operand:         string list
  in expression:
    unzip_single_int twopls