2011-09-05 10 views
5

Tôi đã xác định rất nhiều hàm (ví dụ: 100+), mỗi hàm thực hiện một công việc cụ thể nhưng có cùng chữ ký. Đó là một cái gì đó như:Cách tự động gọi hàm được xác định trong nhiều mô-đun trong cùng một chữ số

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

Những gì tôi muốn làm là cung cấp cho thực tế 'chạy' như người dùng nhập vào, ví dụ rằng:

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

Hiện nay, tôi nhập khẩu tất cả các module đủ điều kiện, và đặt tất cả các run 's vào một danh sách các [Maybe (IO())], vì vậy công trình này:

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

Nhưng khi n phát triển, tôi phải liên tục duy trì một danh sách lớn.

Có cách nào tôi có thể xác định danh sách lớn bằng cách sử dụng TemplateHaskell hay chỉ tải mô-đun tương ứng khi cần trong thời gian chạy mà không phải tách từng mô-đun thành các thư viện được chia sẻ khác nhau.


Dựa trên câu trả lời epsilonhalbe 's, tôi đã làm một số nghiên cứu:

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 

này khối mã in 2 sau khi kết quả của run1run2. Nếu tôi xóa hai dòng cuối cùng, nó chỉ in 0. Có vẻ như các hàm được nhập nhưng không được tham chiếu sẽ không được trích xuất ...

Trả lời

5

Tôi đã từng gặp vấn đề tương tự haskell load module in list có thể điều này sẽ hữu ích.

Bạn có thể tạo danh sách hàm có regexp và chọn hàm theo userinput từ danh sách đó. Tôi không biết nếu bạn phải nhập khẩu tất cả "chạy" đủ điều kiện bằng tay hoặc nếu bạn có thể

import R*.hs (run) 

tôi thà viết một tập tin với run1 = …, run2 = … và tạo ra một danh sách tất cả chạy và một chức năng cụ chọn Hàm nhận hàm từ danh sách hàm có cùng chữ ký.

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

Chú ý: Tôi có không chạy mã này đây chỉ là một dòng tư tưởng đưa vào cú pháp Haskell

tôi hy vọng điều này là hữu ích


Sau khi chỉnh sửa:
Trong ví dụ của tôi, tôi đã viết tất cả run* trong một tệp và ở đó tôi đã tạo danh sách tất cả các hàm chạy, hoạt động ngay lập tức - hãy xem Nucleotide Project của tôi, đặc biệt là các tệp Rules.hsNucleotide.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 

hạnh phúc trở nên hữu ích

+0

Cảm ơn! điều này rất hữu ích, ít nhất 'functionExtractor' là mới đối với tôi. Tôi đã thực hiện một số nghiên cứu và cập nhật bài đăng gốc. – claude

+0

Điều này khá giống với 'prop_ *' của QuickChekc. Khung kiểm tra Haskell 'HTF' thu thập tất cả các bộ test HUnit/QuickCheck trong một tệp sử dụng một bộ tiền xử lý tùy chỉnh' {- # OPTIONS_GHC -F -pgmF htfpp # -} '. Đây là giải pháp cuối cùng tôi muốn sử dụng, nhưng tôi sợ đây là giải pháp duy nhất? – claude

+0

i am chắc chắn nhất chắc chắn rằng đây không phải là giải pháp duy nhất - nhưng tốt nhất tôi có thể đến với. – epsilonhalbe

1

Có hoàn toàn quan trọng mà các run chức năng khác nhau sống trong các module khác nhau? Nếu bạn có thể đặt tất cả trong một mô-đun, bạn có thể làm cho run là một chức năng của Int (hoặc Integer nếu bạn muốn).

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

cảm ơn, đó là giải pháp đầu tiên của tôi. Nhưng tôi phải tách chúng ít nhất thành các đơn vị biên dịch nhỏ, để việc thay đổi thành một 'chạy' sẽ không khiến người khác biên dịch lại. – claude