为什么我不能使用记录选择与存在性量化类型?(Why can't I use record s

2019-07-29 00:59发布

当使用生存类型,我们必须使用模式匹配的语法用于提取forall ED值。 我们不能用普通记录选择的功能。 GHC报告错误和使用模式匹配这一定义的建议yALL

{-# LANGUAGE ExistentialQuantification #-}

data ALL = forall a. Show a => ALL { theA :: a }
-- data ok

xALL :: ALL -> String
xALL (ALL a) = show a
-- pattern matching ok

-- ABOVE: heaven
-- BELOW: hell

yALL :: ALL -> String
yALL all = show $ theA all
-- record selector failed

forall.hs:11:19:
    Cannot use record selector `theA' as a function due to escaped type variables
    Probable fix: use pattern-matching syntax instead
    In the second argument of `($)', namely `theA all'
    In the expression: show $ theA all
    In an equation for `yALL': yALL all = show $ theA all

我的一些数据需要超过5元。 这很难,如果我使用模式匹配,以保持的代码:

func1 (BigData _ _ _ _ elemx _ _) = func2 elemx

有没有好的方法使代码一样,维护或包起来,这样我可以使用某种选择的?

Answer 1:

您可以使用记录语法模式匹配,

func1 BigData{ someField = elemx } = func2 elemx

工作,是巨大的种类要少得多打字。



Answer 2:

存在主义类型更精细的方式比普通工种。 GHC是(正确)使用禁止你theA的功能。 但是想象一下,有没有这样的禁令。 将在该功能有哪些类型? 它必须是这样的:

-- Not a real type signature!
theA :: ALL -> t  -- for a fresh type t on each use of theA; t is an instance of Show

把它非常粗暴, forall使得GHC“忘记”的构造函数的参数的类型; 该类型系统知道所有的是,这种类型的实例Show 。 所以,当你尝试提取构造函数的参数的值,有没有办法恢复原来的类型。

GHC做什么,在幕后,就是上面的假类型签名的评论说,每次对模式匹配ALL构造函数,绑定到构造函数的值的变量被分配有保证是从每一个不同的一种独特类型类型。 举个例子的代码:

case ALL "foo" of
    ALL x -> show x

变量x获得一个唯一的类型,它是从程序中的每一个其它类型的不同,并且不能与任何类型的变量相匹配。 这些独特的类型不逸出到顶层,这是为什么原因theA不能用作函数。



文章来源: Why can't I use record selectors with an existentially quantified type?