Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to determine at runtime, in GHC, whether an abstract value is a function?

Tags:

haskell

ghc

I wonder if it's possible to have a function (somewhat similar to dataToTag#) like:

isFunction# :: a -> Bool

or likely equivalently:

isFunction# :: Any -> Bool

which returns True iff the value passed in as an argument is of a type a -> b (or, for that matter, a => b) at runtime for some types a and b, or a newtype whose underlying type is (so it "sees through" newtypes, but of course not data), without forcing its argument. I didn't see anything like this in GHC.Prim myself, but I may have missed something, or maybe it's possible with a manual CMM primop or something.

Now that the question has occurred to me I'm curious about the answer for its own sake (question Y), but the original reason it occurred to me (question X) is that the complaint usually levelled against seq is that it breaks eta equivalence by making it possible to observe the difference between undefined and \_ -> undefined, and I was wondering if it would be possible to make a version of seq (myseq a = if isFunction# a then flip const a else seq a) that's still "magically polymorphic" (works forall a), but simply leaves functions alone.

like image 416
glaebhoerl Avatar asked Nov 17 '15 19:11

glaebhoerl


1 Answers

No, surely not. How could it know without evaluating the argument?

But to address your question X directly, your proposed myseq is worse than the real seq since it breaks parametricity. Is myseq undefined :: b -> b bottom, or the identity? It depends on whether the type variable a (undefined :: a) was instantiated with a function type or not.

In Haskell you are always allowed to drop a forall a. when a does not appear in the type at all, thanks to parametricity: the choice of a cannot matter. Your myseq would lose that property.

This is also why you could not implement isFunction# without annotating values at runtime with their intended types (isFunction# undefined is similarly meaningless).

like image 140
Reid Barton Avatar answered Oct 16 '22 07:10

Reid Barton