Question

I'm trying to write a function in SML to compute the partial sum of an alternating harmonic series, and for the life of me I can't figure out why the compiler says one of the cases is redundant. I haven't used case statements before(or local, for that matter), but the order of these cases seems right to me.

local
  fun altHarmAux (x:int, y:real) =
    case x of
          1      => 1.0
         | evenP => altHarmAux(x-1, y - y/(real x))
         | oddP  => altHarmAux(x-1, y + y/(real x))
in
fun altHarmonic (a:int) = altHarmAux(a, real a)
end
Was it helpful?

Solution

Even if you have defined the two predicate functions somewhere, they can't be used in a case like that.

whatever you write on the left hand of => will be bound to the value you are matching on, thus the two last matches in your case will match the same input, rendering the last one useless, as the first one will always be used

You will have to apply your predicate function to the value directly, and then match on the result

local
  fun altHarmAux (x, y) =
    case (x, evenP x) of
         (1, _)     => 1.0
       | (_ true)   => altHarmAux(x-1, y - y/(real x))
       | (_, false) => altHarmAux(x-1, y + y/(real x))
in
fun altHarmonic a = altHarmAux(a, real a)
end

or perhaps simpler

local
  fun altHarmAux (1, _) = 1.0
    | altHarmAux (x, y) =
        altHarmAux (x-1, y + (if evenP x then ~y else y) / (real x))
in
  fun altHarmonic a = altHarmAux (a, real a)
end

or

local
  fun altHarmAux (1, _) = 1.0
    | altHarmAux (x, y) =
        if evenP x then
          altHarmAux (x-1, y - y/(real x))
        else
          altHarmAux (x-1, y + y/(real x))
in
  fun altHarmonic a = altHarmAux (a, real a)
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top