Tôi đang làm việc với Data.Typeable và đặc biệt tôi muốn có thể tạo ra các loại chính xác của một loại cụ thể (giả sử *
). Vấn đề mà tôi đang chạy vào đó là TypeRep cho phép chúng ta làm như sau (làm việc với các phiên bản trong GHC 7.8):Có thể lấy Kiểu Loại Constructor trong Haskell không?
let maybeType = typeRep (Proxy :: Proxy Maybe)
let maybeCon = fst (splitTyConApp maybeType)
let badType = mkTyConApp maybeCon [maybeType]
Đây badType
là theo nghĩa các đại diện của các loại Có lẽ Có lẽ, đó là không phải là loại hợp lệ của bất kỳ Loại nào:
> :k Maybe (Maybe)
<interactive>:1:8:
Expecting one more argument to ‘Maybe’
The first argument of ‘Maybe’ should have kind ‘*’,
but ‘Maybe’ has kind ‘* -> *’
In a type in a GHCi command: Maybe (Maybe)
Tôi không thể viết chương trình này ở mức độ đủ thông minh để tránh tạo kiểu như vậy khi chạy. Tôi có thể làm điều này với các điều khoản cấp dữ liệu với TypeRep
. Lý tưởng nhất, tôi sẽ có một cái gì đó giống như
data KindRep = Star | KFun KindRep KindRep
và có một chức năng kindOf
với kindOf Int = Star
(có lẽ thực sự kindOf (Proxy :: Proxy Int) = Star
) và kindOf Maybe = KFun Star Star
, vì vậy mà tôi có thể "loại kiểm tra lại" giá trị TypeRep tôi.
Tôi nghĩ rằng tôi có thể làm điều này bằng tay với một kiểu chữ polykinded như Typeable
, nhưng tôi không muốn viết trường hợp của riêng tôi cho tất cả mọi thứ. Tôi cũng không muốn quay trở lại GHC 7.6 và sử dụng thực tế là có các loại lớp riêng biệt cho các loại có thể đánh loại khác nhau. Tôi mở cửa cho các phương pháp nhận được thông tin này từ GHC.
'typeOf1' và' Typeable1' (và bạn bè) vẫn được xuất từ 'Data.Typeable' ... chúng có thể sử dụng được ở 7.8. –