Hôm nay tôi muốn điều tra nếu có thể xây dựng kiểu dữ liệu theo cách sao cho nó không lưu trữ dữ liệu kiểu chữ ký của nó, nhưng đại diện khác của nó . Vì vậy, đây là nỗ lực của tôi về một GADT trong đó có một nhà xây dựng kiểu của loại a
, nhưng một nhà xây dựng dữ liệu của loại ByteString
.Ví dụ Functor cho GADT có ràng buộc kiểu
{-# LANGUAGE GADTs #-}
import Data.ByteString.Char8
import Data.Serialize
data Serialized a where
MkSerialized :: (Serialize a) => ByteString -> Serialized a
Bây giờ tôi có thể định nghĩa một hàm decode'
theo cách sau:
decode' :: (Serialize a) => Serialized a -> a
decode' (MkSerialized bs) = let Right r = (decode bs) in r
Và nó hoạt động:
let s = MkSerialized (encode "test") :: Serialized String
print $ decode' s -- prints "test"
Vấn đề của tôi bây giờ là tôi muốn trở thành một Serialized
ví dụ của Functor
.
instance Functor Serialized where
fmap f (MkSerialized bs) = MkSerialized (encode (f (right (decode bs))))
where right (Right r) = r
Nhưng tôi gặp lỗi (Serialize b) không thể suy luận được. Làm thế nào tôi có thể hạn chế cá thể Functor để Serialize
được thực thi trong fmap
?
Bạn không thể. 'Functor' không cho phép các ràng buộc về các tham số kiểu được yêu cầu. Có một lớp functor bị hạn chế, ['RFunctor'] (http://hackage.haskell.org/packages/archive/rmonad/0.8/doc/html/Control-RMonad.html#t:RFunctor) trong gói' rmonad' . Có lẽ bạn có thể sử dụng nó. –
Điều này không liên quan đến câu hỏi của bạn - điều này thực sự là không thể với 'Functor' - nhưng tôi cảm thấy có nghĩa vụ phải đề cập đến: Vui lòng không sử dụng' Data.ByteString.Char8' theo mặc định! Đó là một mô-đun bị hỏng khuyến khích mã bị hỏng. Đôi khi có một số cách sử dụng, nhưng mã của bạn hoạt động tốt với 'Data.ByteString', điều này không khuyến khích hiểu lầm về Unicode. – shachaf
Đối với những gì nó có giá trị, bạn có thể tạo kiểu dữ liệu kiểu 'CoYoneda' như' dữ liệu được nối tiếp một nơi mà MkSerialized :: Serialize x => ByteString -> (x -> a) -> Nối tiếp a' lưu trữ một ByteString và một chức năng post-deserialization, và nó có một cá thể 'Functor'. Nhưng tất nhiên là đánh bại mục đích ở đây. – shachaf