2013-02-04 20 views
5

Tôi đã thửHaskell: Hiện tất cả các yếu tố đó là "showable" trên một Hlist

map show . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn()] 

nhưng nó trở

["()"] 
+1

Bạn có _really_ cần lưu trữ dữ liệu được trộn lẫn trong danh sách như vậy không? – AndrewC

+0

Bạn có thể sử dụng một bản ghi để lưu trữ dữ liệu đó dễ dàng hơn, ví dụ và bạn có thể dễ dàng sử dụng các chức năng như hiển thị trên các phần tử vì các loại có sẵn khi chạy. Có loại cố định trong thời gian chạy là một lợi thế, không phải là một bất lợi, vì vậy bạn nên làm điều đó bất cứ khi nào có thể. – AndrewC

+0

Vấn đề này đã được thực hiện để minh họa cho vấn đề của tôi. Dự án tôi đang làm việc ở đây là github.com/rbarreiro/farofias Bước tiếp theo trong dự án là thêm các hàm, không phải là instance của Data.Data. – rbarreiro

Trả lời

5

Mã của bạn không làm những gì bạn mong đợi. Lâu trước khi hành vi năng động của Data.Dynamic đá vào, trình kiểm tra loại Haskell giải quyết các loại. Các loại phần bên phải của biểu thức là

mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn()] :: Typeable b => [b] 

và loại phần bên trái là

map show :: Show a => [a] -> [String] 

như vậy để kết hợp các, loại biến b resp. a được hợp nhất. Nếu bạn đã biên dịch nó từ một tệp Haskell thông thường, trình biên dịch sẽ cung cấp cho bạn một cảnh báo (The type variable `a' is ambigous). Nhưng trong GHCi, thông dịch viên chỉ mặc định là ().

Nhưng điều này khắc phục loại fromDynamic trong biểu thức thành Dynamic -> Maybe(), chọn hiệu quả tất cả các thành phần thuộc loại ().

Nếu bạn buộc trình biên dịch sử dụng loại khác ở đó, ví dụ: bằng cách xác định một chữ ký kiểu, bạn thấy rằng fromDynamic chọn một kiểu khác nhau:

Prelude Data.Dynamic Data.Maybe> map (show :: Integer -> String) . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn()] 
["3"] 

Thật không may, không có cách nào để đạt được những gì bạn muốn: Chọn tất cả các yếu tố mà sự ủng hộ một ví dụ cho thấy loại, như thông tin đó là không có sẵn đến fromDynamic.

7

Vấn đề là fromDynamic phải đi đến một loại monomorphic. Nó được chọn (), nhưng với một chữ ký loại bạn có thể làm cho nó chọn bất kỳ loại nào khác.

Để hiển thị, bạn sẽ cần một số chức năng thử tất cả các loại có thể lần lượt. Có lẽ bạn không muốn lưu trữ dữ liệu như thế này, nhưng muốn lưu trữ nó đi kèm với một số hoạt động (như hiển thị).

Có hai cách bạn có thể nhóm. Yêu thích của tôi là có tất cả các chức năng được áp dụng trước cho giá trị (vì vậy để hiển thị, bạn chỉ cần có được một danh sách các khối của loại String).

Cách khác là đặt các chức năng vào Dynamic (đảm bảo chúng là loại đơn sắc chính xác!) Và sau đó sử dụng dynApply.

+1

ý tưởng hay: "lưu trữ nó đi kèm với một số hoạt động" – rbarreiro

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