2014-04-05 12 views
8

Với biến số Dynamic, nó có thể tận dụng lợi thế của các loại lớp của biến nội bộ mà không có điều kiện về loại chính xác? Ví dụ, giả sử tôi muốn viết một hàm prettyShow. Nếu kiểu nội bộ là một thể hiện của Show, thì chúng ta nên sử dụng cá thể đó; nếu không, chúng ta nên sử dụng cá thể của lớp Dynamic. Trong mã, điều này có thể trông giống như:Kết hợp dữ liệu.Dạng động và loại

prettyShow :: Dynamic -> String 
prettyShow x = case fromDynamic x :: (forall a. Show a => Maybe a) of 
    Nothing -> show x 
    Just y -> show y 

Chỉnh sửa: Vì dường như điều này không thể thực hiện trực tiếp, một số giải pháp tốt có thể thực hiện được là gì?

+0

Tóm lại, không. Tôi rất thích thông tin này để có sẵn, nhưng thông tin về lớp học bị mất và chỉ còn lại một bản thu nhỏ sau khi biên soạn. –

+1

Nhưng chắc chắn có thể có một bảng lớn trong bộ nhớ ở đâu đó liên kết từng typerep với các từ điển lớp học của nó. –

+2

... nhưng không có. –

Trả lời

6

Điều này có thể được thực hiện bằng cách triển khai Dynamic trong thư viện open-typerep (nếu bạn chấp nhận sử dụng lập trình chung và nhiều tiện ích mở rộng GHC).

{-# LANGUAGE TypeOperators #-} 

import Data.TypeRep 

type Types = BoolType :+: IntType :+: ListType 

x, y :: Dynamic Types 
x = toDyn [False,True] 
y = toDyn [1, 2 :: Int] 

test1 = show x 
test2 = show y 

Định nghĩa của show thật đơn giản và bạn có thể sử dụng thư viện để xác định các chức năng khác trên giá trị động.

Trong ví dụ trên, tôi đã sử dụng vũ trụ loại kín Type. Nhưng bằng cách sử dụng các kiểu dữ liệu, bạn có thể định nghĩa các hàm cho các vũ trụ mở. Ví dụ: show chính nó đang mở.

Performance

Một simple benchmark cho thấy Dynamic này là chậm hơn 2-3 lần so với Data.Dynamic trong base cho các loại hình vũ trụ nhỏ được sử dụng ở trên. Việc tăng vũ trụ lên 30 nhà xây dựng kiểu làm cho nó chậm hơn một chút so với 10 lần.

Auto bắt nguồn với nhiều loại mới

open-typerep hỗ trợ việc tạo vũ trụ từ một số ít các loại đại diện được xác định trước. Về nguyên tắc, có thể sử dụng TemplateHaskell cho các biểu diễn tự động lấy cho các kiểu mới, nhưng sẽ khó để tạo ra các cá thể phù hợp cho WitnessPWitness vì chúng phụ thuộc vào những trường hợp khác có sẵn. (Witness được sử dụng, ví dụ: ví dụ Show cho Dynamic.)

+0

Sự khác nhau về hiệu suất giữa điều này và Data.Dynamic là gì? Lớp 'Typeable' của bạn có thể được tự động bắt nguồn cho các kiểu mà tôi không có quyền kiểm soát không? –

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