7
$\begingroup$
Through[(Max - Min)[#]] & @ {1, 2, 3, 4, 5}

gives

5 + (-Min)[{1, 2, 3, 4, 5}]

Of course I can work around by

(Max[#] - Min[#]) & @ {1, 2, 3, 4, 5}

to achieve the desired result

4

But I wonder why Through does not work with Subtract and if there is a direct way to use it.


Edit:

After reading the answers, I see the problem is actually from Times failing to play the role of an operator.

Subtract[Max, Min] // FullForm

gives

Plus[Max, Times[-1, Min]]

Here Times takes a number -1 and a function Min as arguments and is expected to return a function just like what an operator should do, which unfortunately is not the case.

To solve by doing the operator's job manually:

Composition[Times[-1, #] &, Min]

and for the example:

Through[Plus[Max, Composition[Times[-1, #] &, Min]][{1, 2, 3, 4, 5}]]
$\endgroup$
1
  • 3
    $\begingroup$ Compare: Max + Min // FullForm and Max - Min // FullForm $\endgroup$
    – Kuba
    Commented Oct 9, 2015 at 12:03

4 Answers 4

8
$\begingroup$

As Kuba pointed out, the issue here is that Mathematica doesn't do subtraction. From the documentation on Subtract

x-y is converted to x+(-1*y) on input.

And Through only applies the operators at the top level. So

Through[(Max*Min)[{1, 2, 3, 4, 5}]]

and

Through[(Max + Min)[{1, 2, 3, 4, 5}]]

give 5 and 6, respectively, because their FullForm expressions are Times[Max,Min] and Plus[Max,Min].

Through[(Max - Min)[{1, 2, 3, 4, 5}]]

tries to apply Times[-1,Min] to the arguement, but it is not a function. So each element at the top level has to be a function. Simple enough to solve:

Through[(Max + (-Min@# &))[{1, 2, 3, 4, 5}]]

gives the expected answer of 4.

$\endgroup$
1
  • 1
    $\begingroup$ Or for this specific case {i.e., use of Min and Max), -Subtract @@ MinMax[{1, 2, 3, 4, 5}] (note that MinMax is new in v10.1) $\endgroup$
    – Bob Hanlon
    Commented Oct 9, 2015 at 13:29
6
$\begingroup$

Another possibility

Subtract @@ Through[{Max, Min}[{1, 2, 3, 4, 5}]]

4

Here Through returns {5, 1} and then Subtract finished the job

$\endgroup$
4
$\begingroup$

Since the problem has its origins in how Mathematica performs subtractions, just don't use it till the very end:

Through[s[Max, Min][{1, 2, 3, 4, 5}]] /. s -> Subtract
(* 4 *)
$\endgroup$
1
$\begingroup$

Using Comap (new in 14.0)

Subtract @@ Comap[{Max, Min}, Range[5]]

4

Using Query

Subtract @@ Query[{Max, Min}] @ Range[5]

4

Using MinMax (new in 10.1)

-Subtract @@ MinMax @ Range[5]

4

Using ReverseApplied (new in 12.1)

ReverseApplied[Subtract] @@ MinMax @ Range[5]

4

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.