type PT_Int = Int
type PT_String = String
data PolyType = PT_Int Int | PT_String String
给定一个函数 f,我如何编写一个将其提升为 PolyType 的函数?(只是想了解起重)
你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
where f :: * -> *
。
在这些情况下,给定一个函数g :: a -> b
,你想要一个新函数[a] -> [b]
,Maybe a -> Maybe b
或者一般来说f a -> f b
。这正是fmap
来自Functor
.
class Functor f where
fmap :: (a -> b) -> (f a -> f b)
但你PolyType
是单态的(它的类型没有自由变量。准确地说,它有 kind *
)所以它不能是Functor
.
你应该改变你的PolyType
定义
data PolyType a = PT a
现在这是一个有效Functor
的(它只是Identity
Functor
)
instance Functor PolyType where
fmap f (PT a) = PT (f a)
fmap 的类型(专门用于此特定PolyType
实例)是
fmap :: (a -> b) -> PolyType a -> PolyType b