2
votes

Newbie at SML

I have the following code that returns the absolute value of a list. I need it to be of type int list -> real list. Where do I place the statement that converts it to real while constraining this code to a single line?

val myabs = map(fn x => if x >= 0 then x else ~x) [1,~2, 3, ~4];
1

1 Answers

2
votes

You convert an int to real using Real.fromInt:

- Real.fromInt 42;
> val it = 42.0 : real

You can convert an int list into a real list by List.map Real.fromInt:

- List.map Real.fromInt [1, 2, 3];
> val it = [1.0, 2.0, 3.0] : real list

You can convert an integer to its absolute using Int.abs:

- Int.abs ~42;
> val it = 42 : int

You can combine those two functions and so both convert an integer to its absolute and convert it to real:

- (Real.fromInt o Int.abs) ~42;
> val it = 42.0 : real

And you can do this for an entire list using List.map (Real.fromInt o Int.abs):

- List.map (Real.fromInt o Int.abs) [~1, ~2, ~3];
> val it = [1.0, 2.0, 3.0] : real list

You can express that as a single function:

fun myabs xs = List.map (fn x => Real.fromInt (Int.abs x)) xs

And you can shorten this function a bit:

val myabs = List.map (fn x => Real.fromInt (Int.abs x))
val myabs = List.map (fn x => (Real.fromInt o Int.abs) x)
val myabs = List.map (Real.fromInt o Int.abs)

So the only missing pieces were:

  • Instead of if x >= 0 then x else ~x, use Int.abs x.
  • To convert x to real, use Real.fromInt x.
  • To apply multiple functions in sequence, f (g x) or (f o g) x, like math.