和式透镜和棱镜

Lenses and prisms with sum types

此代码无法编译。

{-# LANGUAGE TemplateHaskell #-}

import Control.Lens

data A = A { _a1 :: B, _a2 :: Int }
makeLenses ''A

data B = B1 { _b1 :: Int } | B2
makeLenses ''B

错误是amy.hs:5:21: Not in scope: type constructor or class ‘B’。我有两个问题。

  1. 有没有办法做这样的事情,或者我需要为 B 编写自己的镜头吗?
  2. 给定一个 A,我想将函数应用于 b1 字段(如果该字段存在)。我认为这是棱镜的工作,但我还没有弄清楚该怎么做。

重新安排你的程序如下

{-# LANGUAGE TemplateHaskell #-}

import Control.Lens

data A = A { _a1 :: B, _a2 :: Int }
data B = B1 { _b1 :: Int } | B2

makeLenses ''A 
makeLenses ''B

这个问题与模板 Haskell 的暂存顺序有关(在这种情况下,它可能是一个错误)。

观察到 makeLenses ''B_b1 字段创建了一个 Traversal,因为它只出现在两个构造函数之一中。

b1 :: Traversal' B Int

如果您也使用 Prisms,您需要添加

makePrisms ''B

会产生

_B1 :: Prism' B Int
_B2 :: Prism' B ()