judge-0.1.2.0: src/Logic/Judge/PointedList.hs
{-|
Module : Logic.Judge.PointedList
Description : Re-export 'Data.List.PointedList' with convenience functions.
Copyright : (c) 2017, 2018 N Steenbergen
License : GPL-3
Maintainer : ns@slak.ws
Stability : experimental
Re-export 'Data.List.PointedList' with convenience functions.
-}
{-# LANGUAGE PackageImports #-}
module Logic.Judge.PointedList
( module L
, asList
, toList
, current
, insertAll
, focus
, modify
, update
) where
import "pointedlist" Data.List.PointedList as L hiding (focus)
import "base" Data.Foldable (toList)
-- | Turn a 'PointedList' into a non-pointed list, assuming no particular
-- ordering.
asList :: L.PointedList a -> [a]
asList (L.PointedList prefix x postfix) = x : prefix ++ postfix
-- | Get the current focus of a 'PointedList'.
current :: L.PointedList a -> a
current = L._focus
-- | Add a number of entries to a possibly empty 'PointedList'.
insertAll :: Traversable t => t a -> Maybe (L.PointedList a) -> Maybe (L.PointedList a)
insertAll xs Nothing = L.fromList . toList $ xs
insertAll xs (Just l) = return . foldr L.insertLeft l $ xs
-- | Create a list of variations of the provided 'PointedList', one for each
-- element to take focus.
--
-- This function is a bit sloppy. It assumes no particular order. Note that using
-- 'toList' instead can cause longer (or shorter?) running times.
focus :: L.PointedList a -> [L.PointedList a]
focus = asList . L.positions
-- | Update the focused element of a 'PointedList' using a function that
-- returns 'Just' the new value, or 'Nothing' for deletion.
modify :: L.PointedList a -> (a -> Maybe a) -> Maybe (L.PointedList a)
modify xs f = maybe (L.delete xs) (Just . flip L.replace xs) . f $ current xs
-- | Update the focused element of a 'PointedList' with the value of the
-- 'Just', or delete the element if that value is 'Nothing'.
update :: L.PointedList a -> Maybe a -> Maybe (L.PointedList a)
update xs = modify xs . const