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)
Если вы хотите иметь один регистр, который является строкой, и один регистр, который является целым, вы можете создать новый тип, " теговое объединение " (также называемое "дискриминируемое объединение"), которое разработан, чтобы быть простым в использовании с сопоставлением с образцом. Это будет выглядеть так:
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, я вижу лексикографическое (или буквенное) сравнение. Это то, что вы хотели?