Q:

Haskell function that accepts function or value, then calls function or returns value

How can I write a type declaration and function in Haskell that takes either a function (that itself takes no arguments) or a value. When given a function it calls the function. When given a value it returns the value.
[edit] To give more context, I'm mostly curious how to solve this problem in Haskell without bit twiddling: Designing function f(f(n)) == -n
Sean

A:

I'm mostly curious how to solve this problem in Haskell without bit twiddling: Designing function f(f(n)) == -n

That's actually quite easy to solve:
when :: (a -> Bool) -> (a -> a) -> a -> a
when p f x = if p x then f x else x

f :: Integer -> Integer
f = (+) <$> when even negate <*> signum

How do we derive this? Consider:
f (f n) = (-n) -- (0) - from the interview question

f x     = y    -- (1) - assumption

f y     = (-x) -- (2) - from (0) and (1), f (f x) = (-x)

f (-x)  = (-y) -- (3) - from (0) and (2), f (f y) = (-y)

f (-y)  = x    -- (4) - from (0) and (3), f (f (-x)) = x

Now, if you see the left hand sides of these equations then you'll notice that there are four cases:

f x.
f y.
f (-x).
f (-y).

Notice that the domain of the function f is divided into positive and negative numbers, x and (-x), and y and (-y). Let's assume that x and y together form the set of positive numbers and (-x) and (-y) together form the set of negative numbers.
The set of positive numbers is divided into two proper disjoint subsets, x and y. How do we divide the set of positive numbers into two proper disjoint subsets? Odd and even numbers are a good candidate. Hence, let's assume that x is the set of positive odd numbers and y is the set of positive even numbers.
Another advantage of using odd and even numbers is that when negated odd numbers remain odd and even numbers remain even. Hence, (-x) is the set of negative odd numbers and (-y) is the set of negative even numbers.
Now, consider the four cases again. Notice that the sign only changes when the number is even:

f x = y (sign does not change).
f y = (-x) (sign changes).
f (-x) = (-y) (sign does not change).
f (-y) = x (sign changes).

Hence, we only negate the number when it is even (i.e. when even negate).
Next, we need to convert odd numbers into even numbers and vice versa. The easiest way to do so is to add or subtract one from the number. However, care should be taken that the resulting number is not 0. Consider the special case of 0:
f 0    = z    -- (a) - assumption

f z    = (-0) -- (b) - from (0) and (a), f (f 0) = (-0)

f (-0) = (-z) -- (c) - from (0) and (b), f (f z) = (-z)

(-0)   = 0    -- (d) - reflexivity

f (-0) = f 0  -- (e) - from (d)

(-z)   = z    -- (f) - from (a) and (c) and (e)

z      = 0    -- (g) - from (d) and (f)

f 0    = 0    -- (h) - from (a) and (g)

Hence, f n = 0 if and only if n = 0. So let's consider the neighbors of 0, 1 and (-1). Both of them are odd numbers. Hence, they are not negated. However, they do need to be converted into an even number (except for 0). Hence, 1 is converted into 2 and (-1) is converted into (-2).
Thus, for odd numbers we simply add the sign of the number to the number itself.
Now, consider even numbers. We know:
f 1    = 2    -- (A)

f (-1) = (-2) -- (B)

Therefore:
f 2    = (-1) -- (C), from (0) and (A), f (f 1) = (-1)

f (-2) = 1    -- (D), from (0) and (B), f (f (-1)) = 1

We know that even numbers are always negated. Hence, 2 first becomes (-2) and vice versa. Let the original even number be n. Hence, first we negate n and then add signum n to it:
evenF n    = negate n    + signum n

evenF 2    = negate 2    + signum 2
           = (-2)        + 1
           = (-1)

evenF (-2) = negate (-2) + signum (-2)
           = 2           + (-1)
           = 1

evenF 0    = negate 0    + signum 0
           = 0           + 0
           = 0

Thus, for both the odd case and the even case we add the sign of the original number to when even negate. Therefore, f is defined as:
f :: Integer -> Integer
f = (+) <$> when even negate <*> signum

Hope that helps.

A:

You can't write a function with two different signatures (unless you use typeclasses, but typeclasses are not suitable for this problem). You must solve this in a way that lets you treat both functions and non-function values as the same type. There are two obvious options:

Use a sum type.
f :: Either (Int -> Char) Char -> Char
f (Left g) = g 1
f (Right c) = c

Use const to convert your non-function value into a function that ignores its argument:
f = ($ 42)
f chr         --> '*'
f (const 'a') --> 'a'

However, since this is a very unHaskelly thing to ask for, I suspect that this is an XY problem.

