and*_*opp 15 haskell typeclass heterogeneous
我正在尝试编码一个项目列表,这些项目的类型仅限于某些类型类的实例:
{-# LANGUAGE RankNTypes, TypeSynonymInstances, LiberalTypeSynonyms #-}
module Test where
class Someable a where
some :: a -> String
data Some = Some String
type SomeGroup = forall a. Someable a => [a]
instance Someable Some where
some (Some v) = v
instance Someable SomeGroup where
some (x:xs) = (some x) ++ ", " ++ (some xs)
main = do
putStrLn $ show.some [Some "A", [Some "B", Some "C"]]
Run Code Online (Sandbox Code Playgroud)
但编译失败并出现错误:
Test.hs:14:10:
Illegal polymorphic or qualified type: SomeGroup
In the instance declaration for `Someable SomeGroup'
Run Code Online (Sandbox Code Playgroud)
似乎我甚至没能为类型同义定义实例...
我知道异构集合 wiki文章,但想知道为什么我的方法不起作用 - 我似乎很自然地通过限制集合来定义类型以包含具有类型的项目,这些类型是某种类型的实例.
如果我理解正确,就需要有一个数据类型包装存在主义,以便有一个存储类型类字典和每个元素的地方.
添加一些包装器使它工作:
{-# LANGUAGE ExistentialQuantification, TypeSynonymInstances #-}
module Test where
class Someable a where
some :: a -> String
data Some = Some String
data SomeWrapper = forall a. Someable a => SomeWrapper a
type SomeGroup = [SomeWrapper]
instance Someable Some where
some (Some v) = v
instance Someable SomeWrapper where
some (SomeWrapper v) = some v
instance Someable SomeGroup where
some (x:xs) = (some x) ++ ", " ++ (some xs)
main = do
putStrLn $ some [SomeWrapper (Some "A"), SomeWrapper [SomeWrapper (Some "B"), SomeWrapper (Some "C")]]
Run Code Online (Sandbox Code Playgroud)
当然,这有点难看.不幸的是,我不知道有任何更好的方法.