是否可以使用动态类型输入参数编写函数? 我尝试过模式匹配,但显然它不能像这样工作。
我希望做这样的事情:
fun firstStr (0,n:string) = n
| firstStr (b:string,n:string) = if b>n then n else b;
谢谢。
答案 0 :(得分:10)
StandardML是一种严格的静态类型语言。因此,您不能拥有在第一种情况下接受int而在第二种情况下接受字符串的函数。你得到的错误是
this clause: string * string -> 'Z
previous clauses: int * string -> 'Z
in declaration:
firstStr =
(fn (0,<pat> : string) => n
| (<pat> : string,<pat> : string) => if <exp> > <exp> then n else b)
如果你想让一个是一个字符串,一个是一个int,你可以创建一个新类型,一个“tagged union”(又名“有区别的联合”),它被设计成易于使用模式匹配。它看起来像这样:
datatype Wrapper = Int of int
| String of string
fun firstStr(Int 0, n:string) = n
| firstStr(String b, n:string) = if b>n then n else b
当然,您可能希望为此Wrapper类型找到一些更合适的名称,这在程序的上下文中是有意义的。另请注意,n
上的类型注释并非真正必要;写
fun firstStr(Int 0, n) = n
| firstStr(String b, n) = if b>n then n else b
此外,编译器会告诉您已经发现了一个案例:如果第一个参数是一个不等于零的整数怎么办?
最后,比较b>n
并不清楚你的意思,你想要比较两个字符串的哪个方面?我看到当我比较SML中的两个字符串时,我看到了一个词典(又称字母)比较。那是你想要的吗?
答案 1 :(得分:7)
稍微说一下,假设你有两个参数,每个参数可以是一个字符串或一个整数,如果你有两个字符串你想要字典缩小字符串,如果你有一个字符串你想要那个字符串,并且如果你有两个整数,你不能返回一个字符串。你是做什么?返回string option
类型的值(在http://www.standardml.org/Basis/option.html查找option
,SOME
和NONE
):
datatype string_or_int = String of string
| Int of int
fun firstStr(String a, String b) = SOME (if a < b then a else b)
| firstStr(String a, Int _ ) = SOME a
| firstStr(Int _, String b) = SOME b
| firstStr(Int _, Int _ ) = NONE
函数firstStr
的类型为
string_or_int * string_or_int -> string option
成为精通ML程序员的最快方法是学会先考虑类型。例如,如果你真正想要的是string option * string -> string
类型的函数,你就不需要自己编写它;内置函数getOpt
就是这样做的。另一方面,听起来你想要string option * string -> string
,所以你可以写
fun firstStr(SOME a, b) = if a < b then a else b
| firstStr(NONE, b) = b
并且您不需要在结果上使用SOME
值构造函数或option
类型。
答案 2 :(得分:1)
Polymorphic variants拥有您正在寻找的更多动态属性。你可以看一下,OCaml和SML是非常接近的语言。