Come chiamare in modo dinamico una funzione che ha definito in più moduli nella stessa firma

StackOverflow https://stackoverflow.com/questions/7306578

  •  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 ...

È stato utile?

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top