hom*_*mam 4 polymorphism haskell existential-type gadt
数据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
Run Code Online (Sandbox Code Playgroud)
有些情况:
fiveFoo :: Foo Int
fiveFoo = Foo 5
falseFoo :: Foo Bool
falseFoo = Foo False
Run Code Online (Sandbox Code Playgroud)
我如何定义任何函数b -> Foo a,例如:
getFoo :: (Show a, Typeable a) => String -> Foo a
getFoo "five" = fiveFoo
getFoo "false" = falseFoo
Run Code Online (Sandbox Code Playgroud)
这里getFoo没有打字检查Couldn't match type ‘a’ with ‘Bool’.
我唯一感兴趣的是a上课,Show所以我可以使用getFoo:
main = getLine >>= (print . getFoo)
Run Code Online (Sandbox Code Playgroud)
您可以使用存在类型使数据类型隐藏并"携带"类似于Show周围的类型类.
请注意,使用这样的存在类型被认为是Haskell中的反模式,您可能需要仔细考虑是否真的要这样做:更明确地了解类型通常更简单,更好,并且更不容易出错.
但是,话虽这么说,如果你真的想这样做,下面是你如何在你的例子中使用存在类型:
{-# LANGUAGE ExistentialQuantification #-}
-- This Foo can only be constructed with instances of Show as its argument.
data Foo = forall a. Show a => Foo a
-- Note that there is no "Show a => ..." context here:
-- Foo itself already carries that constraint around with it.
instance Show Foo where
show (Foo a) = show a
getFoo :: String -> Foo
getFoo "five" = Foo 5
getFoo "false" = Foo False
main = print . getFoo =<< getLine
Run Code Online (Sandbox Code Playgroud)
示范:
ghci> main
five
5
ghci> main
false
False
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
479 次 |
| 最近记录: |