2011-12-10 27 views
14

Nói rằng tôi có như sau:Nhận tên trường của bản ghi Haskell dưới dạng danh sách các chuỗi?

data Rec = Rec { 
    alpha :: Int, 
    beta :: Double, 
    phi :: Float 
} 

sample = Rec 1 2.3 4.5 

Tôi hiểu Template Haskell & các reify chức năng có thể làm cho tôi tên trường của kỷ lục. Đó là:

print $(f sample) --> ["alpha", "beta", "phi"] 

Cũng có một tuyên bố rằng điều này có thể được thực hiện mà không cần Mẫu Haskell. Ai đó có thể cung cấp một ví dụ thực hiện cho điều này có thể được thực hiện?

+1

Bạn cũng có thể lấy tên trường mà không có mẫu Haskell. – augustss

+1

@augustss: Làm cách nào? Một số phép thuật đen có thể gõ được? Dù bằng cách nào, hầu hết sử dụng một có thể đặt thông tin này sẽ là một phù hợp tuyệt vời cho mẫu Haskell. – delnan

+3

@delnan Bạn có thể sử dụng 'Data.Data' hoặc bạn chỉ có thể lấy được' Hiển thị', hiển thị 'mẫu' và thực hiện phân tích cú pháp nhỏ của chuỗi đó. – augustss

Trả lời

15

Có thể thực hiện với phiên bản Dữ liệu (hầu hết các phiên bản GHC) hoặc Chung (7.2.x trở lên), mà GHC có thể lấy được cho bạn. Dưới đây là ví dụ về cách kết xuất các trường bản ghi với typeclass dữ liệu:

{-# LANGUAGE DeriveDataTypeable #-} 

import Data.Data 

data Rec = Rec { 
    alpha :: Int, 
    beta :: Double, 
    phi :: Float 
} deriving (Data, Typeable) 

sample = Rec 1 2.3 4.5 

main :: IO() 
main = print . constrFields . toConstr $ sample 
+5

Bạn cũng có thể tránh phải sử dụng một thể hiện kiểu ('sample' trong trường hợp này) bằng cách sử dụng' in. bản đồ constrFields. dataTypeConstrs. dataTypeOf $ (undefined :: Rec) '. Điều này sẽ tạo ra một danh sách tất cả các trường trong tất cả các nhà xây dựng có sẵn (và tất nhiên có thể được điều chỉnh theo ý thích của bạn) – dflemstr

Các vấn đề liên quan