Reputation: 162
I compiled the following code using the command: ./sml /media/ziqi/storage/sml_code/test.sml
:
(* Variables and Declarations *)
type float = real
type count = int and average = real
type float = real and average = float
val m : int = 3+2
val pi : real = 3.14 and e : real = 2.17
val x : float = Math.sin pi
val m : int = 3+2
val n : int = m*m
val n : real = 2.17
let
val m : int = 3
val n : int = m*m
in
m*n
end
val m : int = 2
val r : int =
let
val m : int=3
val n : int=m*m
in
m*n
end * m
val m : int = 0
val x : real = Math.sqrt 2.0
val c : char = #"a"
and I got this error report:
Standard ML of New Jersey (64-bit) v110.99 [built: Tue Mar 23 10:47:59 2021]
[opening /media/ziqi/storage/sml_code/test.sml]
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[library $SMLNJ-BASIS/(basis.cm):basis-common.cm is stable]
[autoloading done]
/media/ziqi/storage/sml_code/test.sml:16.5-24.4 Error: operator is not a function [tycon mismatch]
operator: real
in expression:
2.17 let val m : int = 3
val n : int = m * m in m * n end
It is the following code block that caused the failure:
let
val m : int = 3
val n : int = m*m
in
m*n
end
Then I modified the block causing the issue slightly into a binding statement as follows:
(* Variables and Declarations *)
type float = real
type count = int and average = real
type float = real and average = float
val m : int = 3+2
val pi : real = 3.14 and e : real = 2.17
val x : float = Math.sin pi
val m : int = 3+2
val n : int = m*m
val n : real = 2.17
val h : int =
let
val m : int = 3
val n : int = m*m
in
m*n
end
val m : int = 2
val r : int =
let
val m : int=3
val n : int=m*m
in
m*n
end * m
val m : int = 0
val x : real = Math.sqrt 2.0
val c : char = #"a"
To emphasize, the only difference is that the "let" block causing the issue was modified into the following binding statement:
val h : int =
let
val m : int = 3
val n : int = m*m
in
m*n
end
and the code was compiled and run successfully with the following result:
Standard ML of New Jersey (64-bit) v110.99 [built: Tue Mar 23 10:47:59 2021]
[opening /media/ziqi/storage/sml_code/test.sml]
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[library $SMLNJ-BASIS/(basis.cm):basis-common.cm is stable]
[autoloading done]
type float = real
type count = int
type average = float
type float = real
type average = float
val m = <hidden> : int
val pi = 3.14 : real
val e = 2.17 : real
val x = <hidden> : float
val m = <hidden> : int
val n = <hidden> : int
val n = 2.17 : real
val h = 27 : int
val m = <hidden> : int
val r = 54 : int
val m = 0 : int
val x = 1.41421356237 : real
val c = #"a" : char
It seems that the compiler did not like a "let" expression without being bound to a variable in this case. But compiling the "let" express alone was successful. What is the reason for the failure?
Upvotes: 0
Views: 65
Reputation: 1732
The main issue is that you've (attempted to) put an expression at top level. You can only put declarations at the top level (excepting the REPL-used derived form where e
is treated as val it = e
).
Correspondingly
val n : real = 2.17
let
val m : int = 3
val n : int = m*m
in
m*n
end
is parsed as one declaration. As you have two sequential expressions this would be an application expression, to wit, the application of 2.17
to the let expression. As the type error indicates, this is not permitted as 2.17
does not have a function type.
Upvotes: 1