Как динамически вызвать функцию, которая определена в нескольких модулях в одной и той же подписи

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

  •  25-10-2019
  •  | 
  •  

Вопрос

Я определил много функций (скажем, 100+), каждая из которых выполняет определенную работу, но с той же подписью. Это что -то вроде:

module R001 (run) where run = <do-...>
module R002 (run) where run = <do-...>

Что я хочу сделать, так это предоставить фактический «запуск» в качестве пользовательского ввода, так что:

main = do
         runWith $ read $ getLine
       where
         runWith :: Int -> IO ()
         runWith n = R<n-padded-with-0>.run

В настоящее время я импортирую все квалифицированные модули и ставлю все runв список [Maybe (IO())], так что это работает:

runWith n = case Rs !! (read $ getLine) of 
              Just run -> run
              Nothing -> undefined

Но как n Растет, я должен постоянно вести большой список.

Есть ли способ, которым я могу определить большой список, используя Templatehaskell или просто загрузить соответствующий модуль по мере необходимости во время выполнения без необходимости разделения каждого модуля на разные общие библиотеки.


На основе ЭпсилонхалбеОтвет, я провел некоторое исследование:

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

Этот блок кодовых отпечаток 2 после результатов run1 а также run2. Анкет Если я удалю последние две строки, он просто печатает 0. Кажется, что функции импортируются, но не ссылаются, не будут извлечены ...

Это было полезно?

Решение

Однажды у меня была похожая проблема модуль загрузки Haskell в списке Может, это помогает.

Вы можете создать список функций с помощью REGEXP и выбрать функцию по пользователю в этом списке. Я не знаю, нужно ли вам импортировать все «пробеги», квалифицированные вручную или если вы можете

import R*.hs (run)

Я бы предпочел написать один файл с run1 = …, run2 = … и генерируйте список всех прогонов и функцию выбора функции, которая берет функцию из списка функций с той же подписью типа.

{-# 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

Внимание: у меня есть нет Запустите этот код, это всего лишь поток мышления, вставленную в синтаксис Haskell

Я надеюсь, что это полезно


После редактирования:
В своем примере я написал все run* В одном файле, и там я сгенерировал список всех функций запуска, которые сразу же работали - взглянуть на мой Нуклеотидный проект особенно файлы Rules.hs а также 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

счастлив быть полезным

Другие советы

Абсолютно ли важно, чтобы разные run Функции живут в разных модулях? Если вы можете поместить их все в один модуль, вы можете сделать run быть функцией Int (или же Integer Если вы предпочитаете).

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top