Understanding Haskell interact

There is a function in Haskell’s standard library called interact. It has this type interact :: (String -> String) -> IO ().

Here is the same function in Java:

import java.io.Console;
 
interface Stringer {
  String convertString(String s);
}
 
class Interact {
  // interact :: (String -> String) -> IO ()
  static void interact(Stringer s) {
    final String line = System.console().readLine();
    final String c = s.convertString(line);
    System.out.println(c);
    interact(s);
  }
}

There are some slight differences between the two:

  • In Java, we have had to give a name to the higher-order function (Stringer) with a single method which we have also named (convertString).
  • In Java, we have no guarantee that the implementation of Stringer that is passed to interact is deterministic. In other words, it might perform side-effects and we have no machine-checked guarantee that it will not.

The other major difference is with respect to the evaluation of the arguments. Haskell is call-by-need by default while Java is eagerly evaluated by force. This doesn’t have an impact on understanding the general purpose of Haskell’s interact function by looking at the same function in Java.

That is all. Hope it helps.

4 Responses to “Understanding Haskell interact”

  1. muad Says:

    why are you using recursion instead of a while loop?

  2. Tony Morris Says:

    Why wouldn’t I use recursion? Disciplined programmers rarely use loops.

  3. Tony Morris Says:

    I’m tired of responding to comments that demonstrate stupidity on multiple levels. Very tired.

  4. Adam C Says:

    In all fairness.. muad has a point: Most Java VMs don’t implement tail recursion optimisation, leading to stack overflow issues on large input set.

Leave a Reply