StandardML is a strict, statically typed language. Therefore, you can't have a function which accepts an int in the first case and a string in the second. The error you get is
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)
If you want to have one case which is a string and one case which is an int, you can make a new type, a "tagged union" (aka "discriminated union"), which is designed to be easy to use with pattern matching. It would look like this:
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
Of course, you might want to find some more appropriate name for this Wrapper type, something that makes sense in the context of your programme. Also please note that the type annotation on n
is not really necessary; it would be more idiomatic to write
fun firstStr(Int 0, n) = n
| firstStr(String b, n) = if b>n then n else b
Additionally, the compiler will tell you you have left a case uncovered: What if the first argument is an integer not equal to zero?
Finally, it's not really clear what you mean by the comparison b>n
, what aspect of the two strings did you want to compare? I see that when I compare two strings in SML, I see a lexicographic (aka alphabetic) comparison. Is that what you wanted?