Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 是否有一种方法可以在GHC'中显示函数unpack on;哈斯克尔是谁?_Haskell_Ghc_Exists_Qualifiers - Fatal编程技术网

Haskell 是否有一种方法可以在GHC'中显示函数unpack on;哈斯克尔是谁?

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

我有一个名为Showable的类型,如下所示:

    {-# 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。