0

I have a list of imported functions as a top level binding. I want to get the name of each function in the list without hardcoding them. Because the list is known at compile time using Template Haskell it should be possible to get the names of every list entry, but I haven't yet figured out how to do this.

import qualified Module (function1, function2)

functions = [Module.function1, Module.function2]

main = do
    let names = ?
    print names

Is this even possible or is there another more elegant way?

Edit: I found a way, but it's rather ugly.

functions :: [(f, String)]
functions = $(ListE <$> sequence [TupE <$> sequence [
          pure $ Just $ VarE 'Module.Function
        , Just <$> stringE (show 'Module.Function)
    ]])
Fabus1184
  • 149
  • 7
  • 1
    could you be more specific? do you mean that you have a module with some functions, and you want to have the list of all of them?? or something like that isn't it? Maybe this is a `XY problem` situation. Could you explain why you want that? – lsmor Nov 02 '22 at 15:33
  • 1
    Clearly it is in general not possible to obtain the names of the functions in a list of functions, because they may not _have_ names – you could as well have `functions = [\x -> x + x, \g -> g - 3]`. Why do you put them in a list in the first place? – leftaroundabout Nov 02 '22 at 15:58
  • Names aren't first-class values. They are labels used by the compiler to generate code, not data that is available to that code to manipulate. – chepner Nov 02 '22 at 16:31
  • using TemplateHaskell you can get the names! – Fabus1184 Nov 02 '22 at 16:53
  • [Related.](https://stackoverflow.com/q/49335783/791604) – Daniel Wagner Nov 02 '22 at 19:29

1 Answers1

0

Instead of trying to get the names of entities inside a definition, consider creating the definition given the collection of names instead.

functionNames :: [Name]
functionNames = [ 'function1, 'function2 ]

-- in another module
functions = $(listE (varE <$> functionNames))
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380