【问题标题】:Type variable introduction for existential types存在类型的类型变量介绍
【发布时间】:2021-03-25 14:36:01
【问题描述】:

haskell 中是否有任何绑定器来引入在类型中量化的类型变量(和约束)?

我可以添加一个额外的参数,但它违背了目的。

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}


data Exists x = forall m. Monad m => Exists (m x)

convBad ::  x -> Exists x  
convBad  x = Exists @m (return @m x, undefined) --Not in scope: type variable ‘m’typecheck


data Proxy (m:: * -> *) where Proxy :: Proxy m

convOk ::  Monad m => x -> Proxy m -> Exists x 
convOk  x (_ :: Proxy m) = Exists (return @m x)

【问题讨论】:

  • 为什么return @m xreturn @Identity x 更受欢迎?

标签: haskell existential-type quantifiers rank-n-types


【解决方案1】:

要将类型变量引入作用域,请使用forall(由ExplicitForall 启用,ScopedTypeVariables 隐含):

convWorksNow :: forall m x. Monad m => x -> Exists x  
convWorksNow x = Exists (return @m x)

-- Usage:
ex :: Exists Int
ex = convWorksNow @Maybe 42

但无论您是通过这种方式还是通过Proxy 进行操作,请记住,必须在创建Exists 时选择m。所以调用Exists构造函数的人一定知道m是什么。

如果您希望它是另一种方式 - 即谁解开 Exists 值选择m, - 那么你的forall 应该在里面:

newtype Exists x = Exists (forall m. Monad m => m x)

convInside :: x -> Exists x
convInside x = Exists (return x)

-- Usage:
ex :: Exists Int
ex = convInside 42

main = do
  case ex of
    Exists mx -> mx >>= print  -- Here I choose m ~ IO

  case ex of
    Exists mx -> print (fromMaybe 0 mx)  -- Here I choose m ~ Maybe

另外,正如@dfeuer 在 cmets 中指出的那样,请注意您的原始类型定义(外部带有 forall 的那个)除了表示 x 的类型(与 Proxy 相同)之外几乎没有用处做)。这是因为任何消耗这种价值的人都必须能够使用 any monad m,并且你可以用 monad 做任何事情,除非你知道它是什么。你不能将它绑定到IO 中,因为它不一定是IO,你不能将它与JustNothing 进行模式匹配,因为它不一定是Maybe,等等。你唯一能做的就是用>>=绑定它,但是你会得到它的另一个实例,然后你又回到原点。

【讨论】:

  • 很好的答案,但是 OP 不需要添加 ExplicitForAll 因为 ScopedTypeVariables 已经暗示了它。
  • 谢谢@RobinZigmond,我很怀疑,但没能很快找到文档。
  • ExistsForall 来说似乎是个奇怪的名字。
  • 你可能想指出存在主义版本是非常没用的; Exists xProxy x 基本相同。唯一可能需要这样的存在类型的情况是,如果您使用它来保持值处于活动状态(出于 GC 目的),在这种情况下,您将不需要 Monad 约束。
  • @dfeuer 添加了解释
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
  • 1970-01-01
  • 2020-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多