Haskell中Foo3类型的f3函数实现疑问与类型类字典捕获问题
Haskell中Foo3的实现疑问解答
你的推理完全正确——Haskell确实能在Foo3的构造函数里存储对应类型类的字典指针,因为silly仅返回String,即便a的类型被擦除,也不会影响函数的执行结果。
实现f3的具体方式
不需要额外依赖Dict或Proxy(当然用Dict也可以),借助Haskell的存在量化扩展就能直接实现:
首先开启必要的GHC扩展:
{-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE ConstraintKinds #-}
假设你的类型类和silly函数定义如下:
class Silly a where silly :: a -> String
方式一:隐含存储类型类字典
直接定义存在类型的Foo3,约束会自动携带类型类字典:
data Foo3 = forall a. Silly a => Foo3 a f3 :: Foo3 -> String f3 (Foo3 val) = silly val
方式二:显式使用Dict存储字典
如果你想更明确地管理类型类字典,也可以用constraints包的Dict类型显式存储:
import Data.Constraint (Dict(..)) data Foo3 = forall a. Foo3 a (Dict (Silly a)) f3 :: Foo3 -> String f3 (Foo3 val Dict) = silly val
关于Dict/Proxy的必要性
这里完全不需要Proxy,因为存在类型已经携带了足够的类型类信息——要么通过约束隐含字典,要么通过Dict显式存储。Proxy通常用于仅需要传递类型信息但没有对应值的场景,和当前需求不匹配。
内容的提问来源于stack exchange,提问作者Clinton
相关产品推荐
相关产品推荐

