подъем в тип данных (Haskell)

type PT_Int = Int
type PT_String = String
data PolyType = PT_Int Int | PT_String String

Учитывая функцию f, как мне написать функцию, которая переводит ее в PolyType? (просто пытаюсь понять подъем)


person Paul Kar.    schedule 06.04.2014    source источник


Ответы (1)


Ваш 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
person cdk    schedule 06.04.2014