I moduli di Haskell non sono nemmeno lontanamente entità di prima classe nei modi che questo richiederebbe, temo.
Tuttavia, come commentato da bzn, Template Haskell può essere utilizzato per problemi come questo. Il risultato può essere un po 'goffo, ma se hai davvero bisogno di alcuni hack rapidi per la metaprogrammazione non è una cattiva scelta. Non sono un vero esperto di TH, ma quello che vuoi è piuttosto semplice, con una presa: né "identificatori ambigui" né "nomi di moduli" possono essere catturati o citati in alcun modo, per quanto ne so, quindi tu? Dovremo metterli in stringhe date come argomenti alla funzione TH.
Ecco un rapido e sporco, esempio minimo:
{-# LANGUAGE TemplateHaskell #-}
module MapModuleTH where
import Language.Haskell.TH
mapQual :: [String] -> String -> ExpQ
mapQual ms n = listE $ map (\m -> varE . mkName $ m ++ "." ++ n) ms
mapMQual :: [String] -> String -> ExpQ
mapMQual ms n = appE (varE 'sequence) $ listE $ map (\m -> varE . mkName $ m ++ "." ++ n) ms
È formulato le cose come "l'esecuzione della funzione", che suona più come fare un mucchio di IO
azioni, non solo raccogliendo un elenco di cose, così ho aggiunta una variante che sequenzia anche il risultato.
Si noti che, nonostante l'uso di stringhe qui, questo è ancora staticamente tipizzato - se i nomi qualificati non esistono, oi tipi non corrispondono, si otterrà il tempo di compilazione previsto errore proprio come se avessi scritto tutto a mano.
Ecco un breve esempio di utilizzo. Dati i seguenti:
{-# LANGUAGE TemplateHaskell #-}
module MapModule where
import MapModuleTH
import qualified Test1 as T1
import qualified Test2 as T2
tests = do xs <- $(mapMQual ["T1", "T2"] "test")
putStrLn $ "Count: " ++ show (length xs)
Assumendo gli altri moduli ci sono e definiscono test
, poi nel GHCi possiamo vedere:
> tests
Test 1
Test 2
Count: 2
qual è il problema che si vuole risolvere? Poiché il nome della funzione è noto (ciao), perché non mettere semplicemente le funzioni in una lista '[M1.hello, M2.hello]' e fare qualcosa con quella lista? Immagino che potresti in qualche modo cavartela con TemplateHaskell, ma potrebbe essere eccessivamente complicato. – bzn