type PT_Int = Int
type PT_String = String
data PolyType = PT_Int Int | PT_String String
Учитывая функцию f, как мне написать функцию, которая переводит ее в PolyType? (просто пытаюсь понять подъем)
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
, где 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
является мономорфным (в его типе нет свободной переменной. Если быть точным, он имеет тип *
), поэтому он не может быть 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