Come chiamare in modo dinamico una funzione che ha definito in più moduli nella stessa firma
-
25-10-2019 - |
Domanda
Ho definito un sacco di funzioni (ad esempio, 100 +), ognuno dei quali fanno un lavoro specifico, ma con la stessa firma. Questo è qualcosa di simile:
module R001 (run) where run = <do-...>
module R002 (run) where run = <do-...>
quello che voglio fare è quello di fornire il 'run' attuale input dell'utente, in modo tale che:
main = do
runWith $ read $ getLine
where
runWith :: Int -> IO ()
runWith n = R<n-padded-with-0>.run
Al momento, importare tutti i moduli qualificati, e mettere tutti i run
di in una lista di [Maybe (IO())]
, così funziona:
runWith n = case Rs !! (read $ getLine) of
Just run -> run
Nothing -> undefined
Ma come il n
cresce, devo mantenere continuamente una grande lista.
C'è un modo posso definire il grande elenco utilizzando TemplateHaskell, o semplicemente caricare il modulo corrispondente, se necessario in fase di esecuzione, senza dover separare ogni modulo in diverse librerie condivise.
Sulla base di epsilonhalbe 's risposta, ho fatto qualche ricerca:
import R1 (run1)
import R2 (run2)
test = $(functionExtractor "^run")
main :: IO ()
main = do
putStrLn $ show $ length $ test
run1 -- remove on second attempt
run2 -- remove on second attempt
Questo blocco di stampe di codice 2 seguito i risultati di run1
e run2
. Se rimuovo le ultime due righe, ma si limita a stampare 0. Sembra che le funzioni di importazione, ma non si fa riferimento non verranno estratti ...
Soluzione
Una volta ho avuto un problema simile modulo di carico Haskell in lista forse questo aiuta.
È possibile creare un elenco di funzioni con espressioni regolari e scegliere una funzione da userinput da quella lista. Non so se si deve importare tutti "corre" qualificati a mano o se è possibile
import R*.hs (run)
avrei preferito scrivere un file con run1 = …
, run2 = …
e generare un elenco di tutte le piste e di una funzione di selezione funzione che prende una funzione da un elenco di funzioni con la stessa firma tipo.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.Extract
import myRunFunctions
main = do
let listOfRuns = $(functionExtractor "^run")
putStrLn "please choose a run"
putStrLn $ show listOfRuns
let run = runWith $ read $ getLine
run
where
runWith n = listOfRuns !! n
Attenzione: Ho non eseguire questo codice questo è solo un flusso di pensiero messo in Haskell sintassi
Spero che questo sia utile
Dopo edit:
Nel mio esempio ho scritto tutto run*
in un unico file e non vi ho generato l'elenco di tutte le funzioni Run, che ha funzionato immediatamente - dare un'occhiata al mio Nucleotide Progetto soprattutto la Rules.hs
file e Nucleotide.hs
.
Runs.hs
module Runs where
import Language.Haskell.Extract
listOfRuns = map snd $(functionExtractor "^run")
run1 = …
run2 = …
Main.hs
import Runs
main = do
putStrLn "please choose a run"
putStrLn $ show listOfRuns
let run = runWith $ read $ getLine
run
where
runWith n = listOfRuns !! n
felice di essere utile
Altri suggerimenti
E 'assolutamente fondamentale che le diverse funzioni run
vivono in diversi moduli? Se li si può mettere in un modulo, si potrebbe fare run
una funzione di un Int
(o Integer
se preferite).
module AllMyCircuits where
run 0 = {- do blah blah blah -}
run 1 = {- do blah blah blah -}
run 2 = {- do yikes -}
module Main where
import AllMyCircuits
main = readLn >>= run