Haskell 是否有一种方法可以在GHC'中显示函数unpack on;哈斯克尔是谁?
我有一个名为Showable的类型,如下所示:Haskell 是否有一种方法可以在GHC'中显示函数unpack on;哈斯克尔是谁?,haskell,ghc,exists,qualifiers,Haskell,Ghc,Exists,Qualifiers,我有一个名为Showable的类型,如下所示: {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE ExplicitForAll #-} data Showable = forall a . Show a => Showable a 那么,创建一个打包它的函数就很简单了。我只想写: pack :: forall a . Show a => a -> Showable pack
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE ExplicitForAll #-}
data Showable = forall a . Show a => Showable a
那么,创建一个打包它的函数就很简单了。我只想写:
pack :: forall a . Show a => a -> Showable
pack x = Showable x
然而,似乎不可能创建从Showable解包数据的反向函数。如果我试图颠倒我为“打包和写入”所写的内容:
unpack :: exists a . Show a => Showable -> a
unpack (Showable x) = x
然后我从GHC得到一个错误
我查看了GHC语言扩展的文档,似乎不支持exists关键字。我已经在其他一些Haskell编译器中看到了这一点,但我更希望能够在GHC中实现这一点
有趣的是,我仍然可以在Showable上进行模式匹配,并以这种方式从内部提取数据。所以我可以这样得到它的值,但是如果我想制作一个包含Showable的无点函数,那么我需要解包
那么,是否有某种方法可以在GHC的Haskell中实现解包,也许可以使用类型族或其他一些作为GHC扩展的神秘魔法?您键入的
解包
,无法编写。原因是存在变量a
“转义”模式匹配的范围,并且没有跟踪该行为的工具。引用文件:
模式匹配时,每个模式匹配为每个存在类型变量引入一个新的、不同的类型。这些类型不能与任何其他类型统一,也不能脱离模式匹配的范围。例如,这些片段是不正确的:
f1 (MkFoo a f) = a
结果类型中的“a”是什么?显然,我们不是这个意思:
f1 :: forall a. Foo -> a -- Wrong!
原来的程序完全错了。这是另一种错误
f2 (Baz1 a b) (Baz1 p q) = a==q
可以说a==b
或p==q
,但a==q
是错误的,因为它等同于两个Baz1
构造函数产生的两种不同类型
但是,您可以等效地重写解包
类型,以便不转义存在式:
您键入的
解包
,无法写入。原因是存在变量a
“转义”模式匹配的范围,并且没有跟踪该行为的工具。引用文件:
模式匹配时,每个模式匹配为每个存在类型变量引入一个新的、不同的类型。这些类型不能与任何其他类型统一,也不能脱离模式匹配的范围。例如,这些片段是不正确的:
f1 (MkFoo a f) = a
结果类型中的“a”是什么?显然,我们不是这个意思:
f1 :: forall a. Foo -> a -- Wrong!
原来的程序完全错了。这是另一种错误
f2 (Baz1 a b) (Baz1 p q) = a==q
可以说a==b
或p==q
,但a==q
是错误的,因为它等同于两个Baz1
构造函数产生的两种不同类型
但是,您可以等效地重写解包
类型,以便不转义存在式:
什么是
(unpack(pack(1::Int))::String
呢?我认为这应该是一个编译错误,因为在打包了值之后,您试图给它指定类型,因为打包后,您会丢失有关内部内容的键入信息,所以您不知道是否可以将其类型更改为String。会发生什么(unpack)(pack)呢(1::Int))::String
be?我认为这应该是一个编译错误,因为在打包值之后,您试图给它指定类型,因为打包后,您会丢失有关内部内容的键入信息,因此您不知道是否可以将其类型更改为String。