2011-09-05 2 views
5

각기 특정 작업을 수행하지만 동일한 서명을 가진 많은 함수 (예 : 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을 사용하여 큰 목록을 정의 할 수있는 방법이 없으며 각 모듈을 다른 공유 라이브러리로 분리하지 않고도 런타임시 필요한 모듈을로드 할 수 있습니다. run1run2의 결과 다음과 같은 코드가 인쇄 2의

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 

이 블록 : epsilonhalbe의 답변에 따라


, 나는 몇 가지 조사를했다. 마지막 두 줄을 제거하면 단지 0이 출력됩니다. 가져온 기능이지만 참조되지 않은 함수는 추출되지 않습니다 ...

답변

5

한 번 비슷한 문제가있었습니다. haskell load module in list 아마도 도움이 될 것입니다.

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 

주의 :이이 코드는 하스켈 문법에 넣어 생각의 단지 스트림 하지 실행이

난이 편집 한 후


도움이 될 것입니다 희망 :
내 예제에서는 모든 파일을 한 파일에 모두 run* 썼습니다. 모든 실행 기능 목록이 생성되어 즉시 작동했습니다. - 내 Nucleotide Project 특히 파일 Rules.hsNucleotide.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 

도움이 될 행복

Runs.hs

+0

고마워요! 이것은 매우 유용합니다. 최소한'functionExtractor'는 저에게 새로운 것입니다. 나는 약간의 조사를했고, 최초의 지위를 최신의 것으로 바꿨다. – claude

+0

이것은 QuickChekc의'prop_ * '와 아주 비슷합니다. 하나의 파일에서 모든 HUnit 테스트 케이스/QuickCheck 서브를 수집하는 Haskell 테스트 프레임 워크'HTF'는 커스텀 프리 프로세서'{- # OPTIONS_GHC -F -pgmF htfpp # -}'를 사용합니다. 이것이 내가 사용하기를 원하는 마지막 해결책이지만 이것이 유일한 해결책 일까? – claude

+0

나는 이것이 유일한 해결책이 아니라는 것을 확실히 확신하고 있습니다 -하지만 최선을 다할 수 있습니다. – epsilonhalbe

1

는 다른 run 기능이 다른 모듈에 살고 절대적으로 중요하다? 모듈을 모두 하나의 모듈에 넣을 수 있다면 runInt (또는 원하는 경우 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 
+0

고마워, 그게 내 첫번째 해결책이야. 하지만 적어도 작은 컴파일 단위로 분리해야하므로 하나의'run'으로 변경하면 다른 컴파일이 다시 컴파일되지 않습니다. – claude

관련 문제