如何解包haskell存在类型?
实验存在类型。这似乎是获得某种类型灵活性的好方法 我遇到了一个问题,在我结束一个存在主义类型之后,我将它拆开。我的代码如下:如何解包haskell存在类型?,haskell,types,Haskell,Types,实验存在类型。这似乎是获得某种类型灵活性的好方法 我遇到了一个问题,在我结束一个存在主义类型之后,我将它拆开。我的代码如下: {-# LANGUAGE ExistentialQuantification #-} class Eq a => Blurb a data BlurbBox = forall a . Blurb a => BlurbBox a data Greek = Alpha | Beta deriving Eq instance Blurb Greek data
{-# LANGUAGE ExistentialQuantification #-}
class Eq a => Blurb a
data BlurbBox = forall a . Blurb a => BlurbBox a
data Greek = Alpha | Beta deriving Eq
instance Blurb Greek
data English = Ay | Bee deriving Eq
instance Blurb English
box1 :: BlurbBox
box1 = BlurbBox Alpha
box2 :: BlurbBox
box2 = BlurbBox Ay
main = do
case box1 of
BlurbBox Alpha -> putStrLn "Alpha"
BlurbBox Beta -> putStrLn "Beta"
BlurbBox Ay -> putStrLn "Ay"
BlurbBox Bee -> putStrLn "Bee"
这段代码编译到main,然后抱怨blurbboxalpha的类型。我如何去拆开/拆开一个存在类型?据我所知,你不能这么做。存在类型的全部要点是隐藏一个类型,这样您就可以统一地访问所有“实例”(有点像Java和其他面向对象语言中动态分派子类方法)
因此,在您的示例中,您的“接口”是
BlurbBox
,您可以使用它将某些方法统一应用于不同的BlurbBox,而不必担心内部类型a
是什么(例如,如果Blurb
子类Show
,则您可以拥有[BlurbBox]
并打印列表中的每个元素,而无需知道列表中每个BlurbBox
的确切内部类型)。隐藏类型后,无法*专门化类型。如果您需要这样的操作,请向Blurb
添加一些约束或方法
-- choose one
class (Eq a, Show a) => Blurb a where
printBlurb :: a -> IO ()
instance Blurb Greek where
printBlurb Alpha = putStrLn "Alpha"
...
class (Eq a, Show a) => Blurb a
data Greek deriving (Eq, Show)
...
data BlurbBox = forall a. (Blurb a, Show a) => BlurbBox a
data Greek deriving (Eq, Show)
...
*我非常反对这个,但是如果你真的想
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Dynamic
data Greek = Alpha | Beta deriving (Eq, Typeable)
data English = Ay | Bee deriving (Eq, Typeable)
box1 :: Dynamic
box1 = toDyn Alpha
box2 :: Dynamic
box2 = toDyn Ay
main = do
case fromDynamic box1 of
Just Alpha -> putStrLn "Alpha"
Just Beta -> putStrLn "Beta"
Nothing -> case fromDynamic box1 of
Just Ay -> putStrLn "Ay"
Just Bee -> putStrLn "Bee"
事实上,存在类型是无法解包的,因为它们的全部要点是,期望存在类型的代码必须以完全相同的方式工作(在参数多态性的意义上),而不管存在类型变量是用哪种类型实例化的 你可以更好地理解这一点
data BlurbBox = forall a . Blurb a => BlurbBox a
被翻译成
type BlurbBox = forall b . (forall a . Blurb a => a -> b) -> b
也就是说,BlurbBox是这样一种东西,给定一个适用于所有模糊的多态函数,它可以用于生成将该函数应用于某些(未知)模糊的结果
因此,与不能编写类型为f::a->Int且f String=5和f Bool=3的函数类似,不能在BlurbBox中分派类型为“a”的函数
你可以看看《存在类型》中的一章。它描述了我提供的翻译。您是否有关于如何/在何处进行翻译的链接?BlurbBox(构造函数)的类型为所有a。Blurb a=>a->BlurbBox但类型本身(通常)与..同构?那会有帮助的。TAPL的练习23.4.8和第24.3章很有用,请您详细介绍一下您的第二个版本,使用
Dynamic
s,为什么反对?