данных Foo a
определяется как:Функции для полиморфных типов данных
data Foo a where
Foo :: (Typeable a, Show a) => a -> Foo a
-- perhaps more constructors
instance Show a => Show (Foo a) where
show (Foo a) = show a
с некоторыми экземплярами:
fiveFoo :: Foo Int
fiveFoo = Foo 5
falseFoo :: Foo Bool
falseFoo = Foo False
Как я могу определить любую функцию из b -> Foo a
, например:
getFoo :: (Show a, Typeable a) => String -> Foo a
getFoo "five" = fiveFoo
getFoo "false" = falseFoo
Здесь getFoo
не печатает проверку с помощью Couldn't match type ‘a’ with ‘Bool’
.
Единственное, что меня интересует здесь для a
быть класса Show
так что я могу использовать getFoo
как:
main = getLine >>= (print . getFoo)
Мне это нравится, но Интересно, действительно ли OP действительно нуждается в этом - легко попасть в [экзистенциальный антипаттерн] (https://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/). Однако только ОП знает. – chi
@chi да это экзистенциальная штука, но я не думаю, что это так много антипаттера. Я знаю, что я здесь меньшинство. –
Мы создали здесь тип объединения «Foo»? Является ли это эквивалентом 'data Foo = IFoo Int | BFoo Bool'? – homam