Search code examples
haskellhaskell-lens

How to compose using the _Cons prism


I'm trying to implement a fairly simple piece of code using lenses. However, I've hit a point where I want to be able to add and remove from a list. I've simplified it down to the following:

{-# LANGUAGE TemplateHaskell, FlexibleContexts, ScopedTypeVariables #-}

module LensExample where

import qualified Control.Lens.TH as LensTH
import Control.Lens.Cons (_Cons)
import qualified Control.Lens.Fold

data StackExample = StackExample {
    _internal :: [String]
} deriving (Show)

start = StackExample { _internal = ["Hello", "World"]}

LensTH.makeLenses 'StackExample

popString :: [String] -> Maybe (String, [String])
popString ss = Control.Lens.Fold.preview _Cons ss

popWithPrism :: StackExample -> Maybe (String, StackExample)
popWithPrism s = Control.Lens.Fold.preview _xxx s

How I combine internal and _Cons to produce _xxx?


Solution

  • One possible solution would be:

    popWithPrism :: StackExample -> Maybe (String, StackExample)
    popWithPrism = preview $ internal . _Cons . alongside id (re internal)
    

    The idea is to target the inner list, split it with _Cons, and map each part of the resulting tuple with alongside—in particular the second element, in order to re-apply the StackExample constructor.