1

I know it is not possible to show the function's body since Haskell carries out optimisations, but is it possible to somehow show it's name?

I would like something like

Prelude> f
[Function f]

similar to what other REPL's do (Python, javascript, etc.)

What I get with Haskell is

Prelude> f
<interactive>:2:1: error:
    • No instance for (Show (Integer -> Integer)) arising from a use of ‘print’ (maybe you haven't applied a function to enough arguments?)
    • In a stmt of an interactive GHCi command: print it

which is not helpful in demonstrations.

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
Luke Collins
  • 1,433
  • 3
  • 18
  • 36
  • 1
    btw: If you type `:i f` or `:t f` in prelude you get the name along with some more information about the function, might that help your cause? – flawr Dec 18 '19 at 09:09
  • That is literally something I would like to show, that doing ˋconst fˋ on ˋ5ˋ gives ˋfˋ – Luke Collins Dec 18 '19 at 09:09
  • 4
    It would also break referential transparency. Since in Haskell there should be no functional difference between an expression and its evaluated result. – Willem Van Onsem Dec 18 '19 at 09:13
  • 1
    @LukeCollins For demonstration purposes you could use [lambdabot](https://wiki.haskell.org/Lambdabot) which has the `?src` command, see [this question](https://stackoverflow.com/questions/5786372/how-can-i-view-the-definition-of-a-function-in-haskell-ghci). – flawr Dec 18 '19 at 09:17
  • 5
    Functions don't have names. They are *values*. Variables have names. What is the name of 5? There is none. – n. m. could be an AI Dec 18 '19 at 10:13
  • Even Python is doing something subtly different. Define a function `f`, then set `g = f`, then evaluate `g`. It still reports the name as `f`. Functions are also a special case, because they have a `__name__` attribute which the `def` statement sets. Other values do not. In any case, the variable you are using to *reference* the function isn't relevant to the name. – chepner Dec 18 '19 at 14:17
  • @n.'pronouns'm. Functions are often defined with names, and debugging tools are allowed to break referential transparency. – user253751 Dec 18 '19 at 16:35
  • @user253751 Non-functions are also often defined with names. I have nothing against debugging tools breaking referential transparency, but it isn't clear how exactly they should do that. `x = 5; f y = g y + 1; g z = z * 42; print $ f x` You stop inside `g` and want to see the name of `z`. Is it `z`? Is it `y`? Is it `x`? Is it all of the above? Why? How would a debugging tool implement your option of choice? – n. m. could be an AI Dec 18 '19 at 18:10
  • @n.'pronouns'm. I don't particularly care - you may as well ask what it should print for the name of `z` when you execute `print $ f (2 + 2)`. Here is how I would implement that in a debugging tool: Every function that is defined with a name (syntax `f x = x + 2` for example, but not `f = \x -> x + 2`) is tagged with its name, source filename and line number. Every other function is tagged with its filename and line number. It is not complicated. Yes, `f . g` would return the location of the definition of `(.)`. – user253751 Dec 18 '19 at 18:14

1 Answers1

3

For demonstration purposes, you can try using the simple-reflect package. It allows some forms of symbolic computation:

> foldr f x [1,2,3]
f 1 (f 2 (f 3 x))
> foldl f x [1,2,3]
f (f (f x 1) 2) 3

Beware, it has its own limitations. For instance (f . g) x won't work unless with suitable type annotations. [1] ++ x won't work at all.

Still, if you prepare the examples for a demonstration, you can check them in advance and ensure they work.

chi
  • 111,837
  • 3
  • 133
  • 218