0
votes

Forgive me if this is a dumb question, but is there a typeclass that represents all functions? Like, lets say I have a type like this

data Foo a = Thing a 

instance (Show a) => Show (Foo a) where
    show (Thing a) = show a

And I want to display Thing (\x -> 1). Maybe do some sort o reflection on the method to pretty print some metadata about this?

Trying it I get the following error

> Thing (\x -> 1)

<interactive>:113:1:
    No instance for (Show (t0 -> a0)) arising from a use of `print'
    Possible fix: add an instance declaration for (Show (t0 -> a0))
    In a stmt of an interactive GHCi command: print it

<interactive>:113:14:
    No instance for (Num a0) arising from the literal `1'
    The type variable `a0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Num Double -- Defined in `GHC.Float'
      instance Num Float -- Defined in `GHC.Float'
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in `GHC.Real'
      ...plus 11 others
    In the expression: 1
    In the first argument of `Thing', namely `(\ x -> 1)'
    In the expression: Thing (\ x -> 1)

Which makes sense, since there is no instance of show for t0 -> a0 but I am not sure how to describe an instance of this typeclass?

This isn't for anything production, I am just messing around with Haskell and curious what I can and can't do.

1
If you want a placeholder instance so you can show functions then import Text.Show.Functions. - Thomas M. DuBuisson
Cool, thanks! I knew I was missing something. - devshorts
Functions can't be instances of Show. It seems like it'd be easy, but to the compiler that information is very difficult to obtain after it's been compiled, optimized, and assembled. It's even possible to create new functions at run time, so it makes things pretty complicated. You might be manage it with template haskell that would generate values of type like data Func a = Func a String where the function definition could be shoved into the string and the function itself in the a slot. You could then create an easy instance of Show for it. But this would be very hard to write. - bheklilr
Ok cool, thanks. That makes sense and I wasn't sure it'd be possible or not. Thanks for the answer - devshorts
There's an answer to something else where they use Control.Category to add names to functions and compose them with .. Alternatively you can use Data.Data's typeOf to make a Show instance that just tells you the type of the function, but that doesn't work for polymorphic functions. - not my job

1 Answers

4
votes

Since your goal is just to have fun, you might like Data.Universe.Instances.Show. For a more serious goal, though, you may want to wait until there's been some progress on the Cloud Haskell project, which aims in part to have a way to serialize and deserialize functions so that they can be migrated across machines.