我覺得我要有效地做這樣的事情:哈斯克爾:指定滿足類型類的功能將需要一些特定類型的滿足約束
class (forall z. ListZip z) => PlaneZip p where... --functions using z excluded
在短,但更確切地說,我想有
class A p where ... --definition excluded
class C p where
foo :: (A z) => p (z a) -> a
data Alpha a = ...definition excluded
data Beta a = ...definition excluded
instance A Alpha where --definition excluded
bar :: Beta (Alpha a) -> a
instance C Beta where
foo = bar
這是不可能的,因爲foo
必須允許z
是什麼這是一個A
,不Alpha
明確。我怎麼做到這一點,強制foo
必須採取一些A
但不是任何A
?
更詳細地說,我有許多列表拉鍊,我想製作Comonad的實例。我沒有創建一個列表拉鍊類型,也沒有製作大量的包裝器,而是決定創建一個ListZip類,並創建多個類型的實例。也就是說,
class (Functor z) => ListZip z where
leftMv :: z a -> z a
rightMv :: z a -> z a --further functions excluded
data ListZipInf a = ListZipInf ([a]) a ([a]) deriving (Show)
instance ListZip ListZipInf where... --functions excluded
data ListZipTorus a = ListZipTorus [a] a [a] deriving (Show)
instance ListZip ListZipTorus where.. --functions excluded
現在我想爲2D列表類似拉鍊 - 平面拉鍊 -
data PlaneZipInf a = PlaneZipInf (ListZipInf (ListZipInf a)) deriving (Show)
data PlaneZipTorus a = PlaneZipTorus (ListZipTorus (ListZipTorus a)) deriving (Show)
最後,我想做出類似平面拉鍊類型類,這將讓我有
class PlaneZip p where
unwrap :: (ListZip z) => p (z (z a)) -> z (z a)
counit :: (ListZip z, Comonad z) => p (z (z a)) -> a
counit p =
let zs = unwrap p
in extract $ extract zs
然而,這並不工作,特別是:給定一個方法來「解包」飛機拉鍊構造一種方式來拉一個單一的元素,「專注」出這個名單拉鍊的默認實現,
instance PlaneZip PlaneZipInf where
unwrap (PlaneZipInf zs) = zs
給我一個錯誤 - Could not deduce a ~ (ListZipInf (ListZipInf a))
據預計,對於任何ListZip
工作的功能,但我給它提供一個特定的功能。
我怎麼能表達,我想unwrap
採取型p (z (z a))
,其中z
是某種類型的這是ListZip
一個實例,併產生(z (z a))
?
感謝
看起來你希望在PlaneZip類中有一個關聯類型,在PlaneZip中有一個超類約束,它聲明該類型必須是ListZip的一個實例。也許你甚至想'z'被存在量化。但是,我不確定'p(z(za)) - > z(za)'是否正確,因爲'\(PlaneZipInf zs) - > zs'類型爲'PlaneZipInf a - > ListZipInf(ListZipInf a)'這與上述類型不符。 – user2407038