是否可以编写一个 Haskell 函数来生成隐藏了确切类型参数的参数化类型? IE。就像是f :: T -> (exists a. U a)
?明显的尝试:
{-# LANGUAGE ExistentialQuantification #-}
data D a = D a
data Wrap = forall a. Wrap (D a)
unwrap :: Wrap -> D a
unwrap (Wrap d) = d
无法编译:
Couldn't match type `a1' with `a'
`a1' is a rigid type variable bound by
a pattern with constructor
Wrap :: forall a. D a -> Wrap,
in an equation for `unwrap'
at test.hs:8:9
`a' is a rigid type variable bound by
the type signature for unwrap :: Wrap -> D a at test.hs:7:11
Expected type: D a
Actual type: D a1
In the expression: d
In an equation for `unwrap': unwrap (Wrap d) = d
我知道这是一个人为的例子,但我很好奇是否有办法说服 GHC 我不关心其确切类型D
被参数化,而不为结果引入另一个存在包装类型unwrap
.
澄清一下,我确实想要类型安全,但也希望能够应用函数dToString :: D a -> String
不关心a
(例如,因为它只是从D
) 的结果unwrap
。我意识到还有其他方法可以实现它(例如定义wrapToString (Wrap d) = dToString d
)但我更感兴趣的是是否存在不允许这种隐藏在存在主义之下的根本原因。
是的,您可以,但不是以一种直接的方式。
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE RankNTypes #-}
data D a = D a
data Wrap = forall a. Wrap (D a)
unwrap :: Wrap -> forall r. (forall a. D a -> r) -> r
unwrap (Wrap x) k = k x
test :: D a -> IO ()
test (D a) = putStrLn "Got a D something"
main = unwrap (Wrap (D 5)) test
您不能退回D something_unknown
从你的函数中,但你可以提取它并立即将其传递给另一个接受的函数D a
, 如图所示。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)