Combo lenses and prisms for sums of products?

北城以北 提交于 2019-12-04 17:00:43

You can take a detour through another generated Iso to get this behavior. (makePrisms generates Isos when applied to a type with a single constructor)

{-# LANGUAGE TemplateHaskell #-}

module Demo where

import Control.Lens

data Exp = Lit Int | Var String | Lambda String Exp
data LambdaRec = LambdaRec { _bound::String, _body::Exp }

makePrisms ''Exp
makePrisms ''LambdaRec
makeLenses ''LambdaRec

_ExpLambdaRec :: Prism' Exp LambdaRec
_ExpLambdaRec = _Lambda . from _LambdaRec

-- Example using _ExpLambdaRec
expBound :: Traversal' Exp String
expBound = _ExpLambdaRec . bound

Note that thanks to optimizations that GHC can do that this intermediate record type isn't necessarily used in the generated code.

getBound :: Exp -> Maybe String
getBound = preview expBound

-- Generated core for getBound
--
-- getBound1 =
--   \ eta_B1 ->
--     case eta_B1 of _ {
--       __DEFAULT -> (Nothing) `cast` ...;
--       Lambda y1_a6XB y2_a6XC -> (Just y1_a6XB) `cast` ...
--     }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!