type PT_Int = Int
type PT_String = String
data PolyType = PT_Int Int | PT_String String
给定函数f,如何编写将其提升为PolyType的函数? (只是想了解解除)
答案 0 :(得分:4)
您的PolyType
相当于Either Int String
。如果您之前没有看到Either
:
data Either a b = Left a | Right b
所以你可以拥有像
这样的功能liftP :: (Either Int String -> a) -> PolyType -> a
liftP f poly = case poly of
PT_Int i -> f (Left i)
PT_String s -> f (Right s)
PolyType
包含Int
或String
,因此您只能解除在Int
和String
上定义的功能。
那就是说,我不认为这就是你所追求的。术语"解除"通常用于[a]
,Maybe a
,(->) a
等多态数据类型的上下文中,或者通常用于f a
的某种类型f :: * -> *
。
在这些情况下,给定一个函数g :: a -> b
,您需要一个新函数[a] -> [b]
,Maybe a -> Maybe b
或一般f a -> f b
。这正是来自fmap
的{{1}}。
Functor
但你的class Functor f where
fmap :: (a -> b) -> (f a -> f b)
是单态的(它的类型中没有自由变量。确切地说,它有PolyType
种类}所以它不能成为{ {1}}。
您可以将*
的定义更改为
Functor
现在这是一个有效的PolyType
(它只是data PolyType a = PT a
Functor
)
Identity
fmap的类型(专门针对此特定Functor
实例)是
instance Functor PolyType where
fmap f (PT a) = PT (f a)