2011-11-29 27 views
10

Tôi đã chơi với việc tạo một DSEL được gõ đầy đủ trong Haskell bằng GADT và như vậy đối với một AST hoàn toàn an toàn, và có vẻ như việc thực hiện một trình biên dịch chính xác yêu cầu các cấu trúc như bản đồ từ các kiểu Haskell cho cả hai loại và giá trị (môi trường đã nhập) và như vậy có thể được hiểu bởi hệ thống kiểu Haskell. C++ có thư viện Boost.Fusion với các cấu trúc như thế này (loại -> bản đồ giá trị, vectơ của các giá trị đã nhập, v.v.). Data.Tuple sẽ chăm sóc các chuỗi, nhưng có phiên bản Haskell của những thứ như Boost.Fusion map s không?Haskell tương đương với Boost.Fusion

+0

Lý do cho phiếu giảm giá là gì? –

+0

Khi bạn mô tả một "trình biên dịch", bạn đang biên dịch gì từ/đến? Nếu bạn có GADT, bạn có thực sự viết thông dịch viên cho nó hay một hàm từ GADT, ví dụ, mã C? – sclv

+0

Hoặc là - các vấn đề tương tự sẽ xuất hiện trong bất cứ điều gì dịch AST đã nhập thành bất kỳ thứ gì khác hoặc chạy nó. –

Trả lời

10

Nhìn vào gói dependent-map. Tôi đã không sử dụng nó bản thân mình, nhưng nó dường như làm những gì bạn đang yêu cầu. Nếu bạn thực sự cần sử dụng tính bình đẳng kiểu (và kiểu chỉ) thì bạn có thể cần phải đồng ý về một giá trị mặc định hoặc sử dụng một khóa TypeRep để thay thế.

1

Bạn đang tìm kiếm Data.Map và danh sách? (ví dụ: [Int]).

+0

Không, vì các phần tử cần phải có các loại khác nhau và ở đây các khóa là các loại. Tôi muốn một cái gì đó mà thực hiện một ánh xạ như '(Int-> 5, Float ->" foo ")' trong một giá trị (không phải là một loại lớp cung cấp cho một bản đồ toàn cầu). Tôi biết làm thế nào để viết nó bằng tay (tôi nghĩ), nhưng tôi đã tự hỏi nếu ai đó đã làm nó rồi. –

+1

Thử gói bản đồ phụ thuộc: http://hackage.haskell.org/package/dependent-map –

+0

@NathanHowell: Bạn có thể đăng câu trả lời này làm câu trả lời không? Tôi sẽ kiểm tra xem nó ra, nhưng nó trông từ tài liệu như nó là những gì tôi yêu cầu. –

4

Đầu tiên, câu trả lời hoàn toàn quá hiển nhiên là bạn có thể dễ dàng viết một "loại-> giá trị bản đồ" sử dụng Typeable (một phần của thư viện cơ sở):

import Data.Typeable 
import Data.Map 

type TypeMap a = Map TypeRep a 

insertT :: Typeable k => k -> a -> Map k a -> Map k a 
insertT v = insert (typeOf k) 

lookupT :: Typeable k => k -> a -> Map k a -> Map k a 
lookupT v = lookup (typeOf k) 

Bây giờ bạn có thể sử dụng mã như insertT (undefined :: Int) 5 để chèn phần tử theo loại.

Nhưng nhìn vào Fusion, điều này không thực sự trông giống như những gì bạn có thể sau. Có vẻ như nó cho phép bạn xây dựng mã làm việc trên các cấu trúc dữ liệu tùy ý? Đó là một cái gì đó mà trong Haskell được gọi là "Scrap Boilerplate của bạn" lập trình chung chung. Xem các chi tiết papers hoặc hackage để biết chi tiết, nhưng nó cho phép bạn viết mã xử lý các cấu trúc dữ liệu tùy ý và chọn ra các giá trị của các loại nhất định.

Một vài điều khác mà tôi thấy về Fusion có thể được mô phỏng bằng các thư viện như HList hoặc có thể là fclabels. Nhưng nó thực sự là thực sự là để nói nhiều hơn mà không cần nhìn vào những gì bạn thực sự cần.

+0

'TypeMap' của bạn sẽ hoạt động nhưng yêu cầu một' unsafeCoerce' để thuyết phục trình biên dịch rằng kiểu ở bên phải khớp với 'TypeRep' ở bên trái (hoặc' Data.Dynamic'). HList cũng rất thú vị; fclabels trông giống như nó cung cấp dây khóa kéo.Tôi không cần lập trình phản chiếu/dữ liệu chung chung trên các kiểu dữ liệu tùy ý, vì vậy tôi không nghĩ SYB sẽ giúp đỡ. –

+0

Vâng, tôi không chắc liệu bạn có muốn giá trị được đề cập có loại chỉ mục của nó hay không. Nếu bạn muốn điều đó, có thể bạn nên sử dụng 'HList' (nếu bạn biết các khóa của bản đồ tĩnh) hoặc xây dựng bản đồ tương tự bằng cách sử dụng' Dynamic' trong các giá trị để lấy xung quanh 'unsafeCoerce'. –

3

Như đã đề cập trước đây, dependent-map có vẻ như lựa chọn đúng đắn cho phía bản đồ của sự vật, nhưng tôi muốn khuyên bạn nên nhìn vào giao diện HArray của hlist như một thay thế cho tay tung hứng tuples.