使用用户定义的数据类型作为函数参数的类型

时间:2018-01-05 08:12:29

标签: sml smlnj

我定义了以下数据类型:

datatype Arguments
  = IntPair of int * int
  | RealTriple of real * real * real
  | StringSingle of string;

datatype OutputArgs = IntNum of int | RealNum of real | Str of string;

我尝试创建一个函数MultiFunc: Arguments -> OutputArgs

fun MultiFunc(RealTriple (x, y, z)) : OutputArgs = RealNum ((x+y+z)/3.0)
  | MultiFunc(IntPair (x,y)) : OutputArgs = IntNum (x+y)
  | MultiFunc(StringSingle(s)) : OutputArgs = Str (implode(rev(explode(s))));

然而,当我致电MultiFunc(1.0,2.0,3.0)时,我收到以下错误:

stdIn:588.1-588.23 Error: operator and operand don't agree [tycon mismatch]
  operator domain: Arguments
  operand:         real * real * real
  in expression:
    MultiFunc (1.0,2.0,3.0)

即。由于某种原因,它不会将输入参数识别为RealTriple

2 个答案:

答案 0 :(得分:3)

MultiFunc(1.0,2.0,3.0)
     

由于某种原因,它无法将输入参数识别为RealTriple

那是因为输入不是RealTriple,而是3元组的实数(real * real * real)。

尝试改为:

- MultiFunc (RealTriple (1.0, 2.0, 3.0));
> val it = RealNum 2.0 : OutputArgs

以下是我写这个函数的方法:

fun multiFunc (RealTriple (x, y, z)) = RealNum ((x+y+z)/3.0)
  | multiFunc (IntPair (x,y)) = IntNum (x+y)
  | multiFunc (StringSingle s) = Str (implode (rev (explode s)))

通过让函数名以小写字母开头,我将它们与RealTriple之类的值构造函数区别开来。我不写: OutputArgs但是要改为推断函数的类型。我省略了多余的括号,如StringSingle(s)explode(s):在许多编程语言中,函数调用必须有括号。在标准ML中,函数应用程序是通过并置左侧的函数和右侧的由空格分隔的参数来实现的。因此,在f x上调用fx,而在(f x) yf x为“y返回,用作函数”。

答案 1 :(得分:2)

您需要将三元组包装到相应的数据构造函数中,以向编译器解释您的类型为Arguments的内容,而不仅仅是实数的三倍:

MultiFunc (RealTriple (1.0,2.0,3.0))