haskell - 在模式同义词中调用函数
问题描述
我在拉链上实现了一些功能,其中孔类型是存在量化的,即我有这样的东西:
data Zipper (c :: Type -> Constraint) ... =
forall hole. (c hole, ...) =>
Zipper hole ...
其中点表示我认为与我的问题无关的实现细节。现在考虑一些数据类型:
data Tree = Fork Tree Tree | Leaf Int
我想要的是能够检查我在树中的位置。在简单递归的情况下,实现此目的的标准方法是模式匹配:
case hole of
Fork _ _ -> doSomething
Leaf _ -> doSomethingElse
然而,洞的类型是存在量化的,所以简单的模式匹配是行不通的。我的想法是使用类型类
class WhereAmI p a where
position :: a -> p a
data Position :: Type -> Type where
C_Leaf :: Position Tree
C_Fork :: Position Tree
-- possibly more constructors if we're traversing
-- multiple data structures
然后我可以做类似的事情
f :: Zipper (WhereAmI Position) Tree -> Int
f (Zipper hole _) = case position hole of
C_Leaf -> let (Leaf x) = hole in x
otherwise -> ...
然而,我想要的是使用类似这样的魔法来替换C_Leaf
(at @"Leaf"
即使用原始构造函数名称)
class WhereAmI' p (a :: Symbol) where
position' :: Proxy a -> p
instance WhereAmI' (Position Tree) "Leaf" where
position' _ = C_Leaf
instance WhereAmI' (Position Tree) "Fork" where
position' _ = C_Fork
at :: forall a p. WhereAmI' p a => p
at = position (Proxy :: Proxy a)
这甚至可以工作,除了我不能at
用作模式,如果我尝试将其设为模式,GHC 会抱怨模式中的解析错误......
有没有一些聪明的方法来实现我在这里描述的内容?
解决方案
推荐阅读
- javascript - Cakephp:使用javascript时,按钮的名称不包含在帖子中
- python - 为什么调用我的函数会引发 NameError?
- python - 提高从 pandas 列中提取信息的速度
- sql - 需要帮助从字符串中提取子字符串直到特定长度之前的最后一个空格
- angular - 如何使用 *ngFor 渲染二维数组
- html - URL - 使用 R 进行网页抓取
- plugins - 如何修复错误:“dex base.apk 的校验和不匹配”
- php - Laravel 5.8 全局设置区域设置
- javascript - 如何遍历多个json数组并显示结果
- amazon-web-services - AWS Cognito:如何从服务器终止/关闭用户会话