@@ -6,43 +6,44 @@ module Data.Lens.Index
66import Prelude
77
88import Data.Array as A
9+ import Data.Array.NonEmpty as NEA
910import Data.Identity (Identity )
1011import Data.Lens.Internal.Wander (wander )
1112import Data.Lens.Types (Traversal' )
1213import Data.Map as M
1314import Data.Maybe (Maybe , maybe , fromMaybe )
1415import Data.Set as S
15- import Foreign.Object as FO
1616import Data.Traversable (traverse )
17+ import Foreign.Object as FO
1718
1819-- | `Index` is a type class whose instances are optics used when:
1920-- | 1. The focus element might not be present.
20- -- | 2. You either cannot or do not want to add new elements or delete existing ones.
21+ -- | 2. You either cannot or do not want to add new elements or delete existing ones.
2122-- |
2223-- | `Array` is a typical example:
2324-- |
24- -- | ```purescript
25+ -- | ```purescript
2526-- | preview (ix 1) [0, 1, 2] == Just 1
2627-- |
2728-- | set (ix 1) 8888 [0, 1, 2] == [0,8888,2]
2829-- | ```
2930-- |
30- -- | Note the use of `preview` rather `view`. That's because the optic is
31+ -- | Note the use of `preview` rather `view`. That's because the optic is
3132-- | a `Data.Lens.Traversal` tailored to the case where there's a single element
3233-- | of interest.
33- -- |
34+ -- |
3435-- | Another common use is a `Map` that you don't want to either grow or shrink:
3536-- |
36- -- | ```purescript
37+ -- | ```purescript
3738-- | (set (ix "k") "new" $ Map.singleton "k" "old") == Map.singleton "k" "new"
38- -- |
39+ -- |
3940-- | (set (ix "k") "new" $ Map.empty) == Map.empty
4041-- | ```
4142-- |
4243-- | Note the second line: an attempt to `set` a missing focus element
4344-- | leaves the original whole unchanged.
4445-- |
45- -- | If you *do* want to add or delete elements, see `Data.Lens.At`.
46+ -- | If you *do* want to add or delete elements, see `Data.Lens.At`.
4647
4748class Index m a b | m -> a , m -> b where
4849 ix :: a -> Traversal' m b
@@ -67,6 +68,14 @@ instance indexArray :: Index (Array a) Int a where
6768 (pure xs)
6869 (coalg >>> map \x -> fromMaybe xs (A .updateAt n x xs))
6970
71+ instance indexNonEmptyArray :: Index (NEA.NonEmptyArray a ) Int a where
72+ ix n =
73+ wander \coalg xs ->
74+ xs NEA .!! n #
75+ maybe
76+ (pure xs)
77+ (coalg >>> map \x -> fromMaybe xs (NEA .updateAt n x xs))
78+
7079instance indexSet :: Ord a => Index (S.Set a ) a Unit where
7180 ix x =
7281 wander \coalg ->
0 commit comments