Reputation: 195
I'm trying to subtract two functions(both with type real) in moscow ml. It then says "Overloaded - cannot be applied to arguments of type real -> real. So how should I write the function?
fun CircleArea x = x*x*Math.pi
fun SquareArea x:real = 4*x*x
fun Area x = SquareArea - CircleArea
Upvotes: 3
Views: 641
Reputation: 50928
Subtraction of functions like we have in mathematics isn't provided as a built-in operator. You can, however, define your own.
Mathematically speaking, we define
(f - g)(x) = f(x) - g(x)
We can replicate this definition in SML as follows:
infix 5 --
fun f -- g = fn x => f x - g x
What this does is produce an operator, --
, such that f -- g
produces the function corresponding to fn x => f x - g x
, i.e. the function that given an x
calculates f x - g x
.
Note, due to the type-ambiguity in the -
operator, it'll default to let you subtract 'a -> int
functions. In your case you'll want to subtract 'a -> real
functions, so you'll need a slight modification:
infix 5 --
fun f -- g = fn x => f x - g x : real
If you use this --
-operator, you will be able to define your Area
function like so:
val area = squareArea -- circleArea;
(I took the liberty of making the first letter of function names lowercase, to match the SML naming conventions.)
Upvotes: 2
Reputation: 16145
You probably don't actually want to subtract one function from another, but the return values of those functions once they are applied. You could achieve this in the following way:
fun Area x = (SquareArea x) - (CircleArea x)
The parentheses are not mandatory, since function application (i.e. the space between SquareArea
and x
) binds tighter than any binary operator, including -
.
You should consider using the following naming convention in ML: Regular functions have a lowercase starting symbol, while value constructors for algebraic types have uppercase starting symbols. For example:
fun area x = squareArea x - circleArea x
But:
datatype shape = Square of int * int
| Circle of int
Upvotes: 5