没有数据构造函数的存在量化

Existential quantification without data constructors

通过在数据构造器中打包字典,很容易得到存在量化。

{-# LANGUAGE GADTs #-}

data S where
  MkS :: Show a => a -> S

f :: Int -> S
f x = case x of
  0 -> MkS 0
  _ -> MkS "non-zero"

GHC 指南中的相关 section 明确讨论了 "Existentially quantified data constructors"。是否可以编写相同的代码但不引入额外的数据类型和构造函数,即带有签名的东西

f :: Int -> (exists a. Show a => a)
f x = case x of
  0 -> 0
  _ -> "non-zero"

如果没有,是否有书面说明为什么存在此限制?避免添加新量词?

借用 Colin 的评论并查看此 answer,可以在没有 exists 量词的情况下编写相同代码的 CPS-ed 版本。

f' :: Int -> ((forall a. Show a => a -> r) -> r)
f' x = case x of
  0 -> \k -> k 0
  _ -> \k -> k "non-zero"

虽然这并不理想,但它确实解决了问题而无需引入额外的数据类型。