2013-05-04 61 views
2

我有一個摺疊函數,我想用於許多不同的結構,每個結構都帶有任意命名的字段。因此,我需要告訴fold函數傳遞了哪種結構,以及訪問哪個字段。我需要的是這樣的:球拍,函數中的訪問結構字段

(define-struct test (element)) 
(define test_struct (make-test 0)) 

(define (getfield elementname structure) 
    ((typeof structure)-elementname structure)) 

(getfield element test_struct) 

最後一行則等同於:

(test-element test_struct) 

當然以上都不是正確的語法,但它應該顯示我什麼都對。基於一些其他問題在這裏stackoverflow,似乎答案與syntax有關,但我不知道如何工作。

回答

2

什麼都不行

雖然可以introspect the struct type at run time,我看不出你如何能使用在宏在編譯時間。因爲在編譯的時候,你沒有什麼給object-name只是一塊語法 - 不是一個類型的現場結構對象:

(require (for-syntax racket/syntax)) 
(define-syntax (get-field stx) 
    (syntax-case stx() 
    [(_ field-name s) 
    (with-syntax ([id (format-id stx 
            "~a-~a" 
            (object-name #'s) ; um, yeah, this won't work 
            #'field-name)]) 
     #'(id s))])) 

什麼工作呢?

  1. 你可以讓你的fold -ish函數接受一個額外的參數 - 這是字段存取函數。在你的例子中,它將是訪問test結構類型的element字段的test-element函數。

    這與Racket的sort有一個可選的#:key extract-key參數類似,該參數是應用於每個項目以獲取用於排序的值的函數。例如,如果您正在整理teststruct s的列表,則可以通過test-element訪問器函數。

    - 或 -

  2. 你可以使用一本字典,而不是一個結構。你上面有什麼,但使用hasheq等效:

    (define test (hasheq 'element 0)) 
    (hash-ref test 'element) ; => 0 
    
+0

非常感謝您的回答。我最終選擇了第一個選項。它有點像黑客,但是嘿,有時候這只是需要的! – NickO 2013-05-06 02:06:27

+0

@NickO我應該提到在Racket中有這樣的先例:可選的'#:key sort-key'作爲'sort'的參數。這是適用於該項目以獲得「有趣」價值的功能。 – 2013-05-06 12:05:11