为GADTs制作镜头(Haskell)

8

是否有类似于 makeLenses 的东西可以用在 GADTs 上?假设我们有一个简单的 GADT,例如:

data D a b where
  D :: (Ord a, Ord b) => !a -> !b -> D a b

有没有一种方法可以通过传递构造函数和字段名称列表来自动生成镜头?

2
我必须问一下:是否有可能手写它们? - dfeuer
1个回答

7

我认为这个任务无法自动完成,但在这种情况下手写一些镜头并不难:

{-# LANGUAGE GADTs #-}

import Control.Lens

data D a b where
  D :: (Ord a, Ord b) => !a -> !b -> D a b

field1 :: Lens' (D a b) a
field1 f (D x y) = fmap (\x' -> D x' y) (f x)

field2 :: Lens' (D a b) b
field2 f (D x y) = fmap (\y' -> D x y') (f y)

{- If you want type-changing lenses, you can also use these signatures.
 - Note that then the target type Ord constraint has to escape.

field1 :: (Ord a2) => Lens (D a1 b) (D a2 b) a1 a2
field2 :: (Ord b2) => Lens (D a b1) (D a b2) b1 b2
 -}

似乎有一个相关的GitHub问题,Kmett声称他们无法为存在量化字段创建镜头。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接