| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Termonad.FocusList
Synopsis
- data Focus
- foldFocus :: b -> (Int -> b) -> Focus -> b
- _Focus :: Prism' Focus Int
- _NoFocus :: Prism' Focus ()
- hasFocus :: Focus -> Bool
- unsafeGetFocus :: Focus -> Int
- data FocusList a = FocusList {
- focusListFocus :: !Focus
- focusListLen :: !Int
- focusList :: !(IntMap a)
- lensFocusListLen :: forall a. Lens' (FocusList a) Int
- lensFocusListFocus :: forall a. Lens' (FocusList a) Focus
- lensFocusList :: forall a a. Lens (FocusList a) (FocusList a) (IntMap a) (IntMap a)
- debugFL :: Show a => FocusList a -> String
- lensFocusListAt :: Int -> Lens' (FocusList a) (Maybe a)
- invariantFL :: FocusList a -> Bool
- unsafeFLFromList :: Focus -> [a] -> FocusList a
- focusItemGetter :: Getter (FocusList a) (Maybe a)
- flFromList :: Focus -> [a] -> Maybe (FocusList a)
- singletonFL :: a -> FocusList a
- emptyFL :: FocusList a
- isEmptyFL :: FocusList a -> Bool
- appendFL :: FocusList a -> a -> FocusList a
- appendSetFocusFL :: FocusList a -> a -> FocusList a
- prependFL :: a -> FocusList a -> FocusList a
- unsafeGetFLFocus :: FocusList a -> Int
- unsafeGetFLFocusItem :: FocusList a -> a
- getFLFocusItem :: FocusList a -> Maybe a
- unsafeInsertNewFL :: Int -> a -> FocusList a -> FocusList a
- unsafeShiftUpFrom :: forall a. Int -> FocusList a -> FocusList a
- unsafeLookup :: Int -> IntMap a -> a
- lookupFL :: Int -> FocusList a -> Maybe a
- insertFL :: Int -> a -> FocusList a -> Maybe (FocusList a)
- unsafeRemove :: Int -> FocusList a -> FocusList a
- unsafeShiftDownFrom :: forall a. Int -> FocusList a -> FocusList a
- removeFL :: Int -> FocusList a -> Maybe (FocusList a)
- indexOfFL :: Eq a => a -> FocusList a -> Maybe Int
- deleteFL :: forall a. Eq a => a -> FocusList a -> FocusList a
- setFocusFL :: Int -> FocusList a -> Maybe (FocusList a)
- updateFocusFL :: Int -> FocusList a -> Maybe (a, FocusList a)
- findFL :: (Int -> a -> Bool) -> FocusList a -> Maybe (Int, a)
- moveFromToFL :: Show a => Int -> Int -> FocusList a -> Maybe (FocusList a)
Documentation
>>>:set -XFlexibleContexts>>>:set -XScopedTypeVariables
Instances
| Eq Focus Source # | |
| Ord Focus Source # |
NoFocus < Focus a |
| Read Focus Source # | |
| Show Focus Source # | |
| Generic Focus Source # | |
| CoArbitrary Focus Source # | |
Defined in Termonad.FocusList Methods coarbitrary :: Focus -> Gen b -> Gen b # | |
| type Rep Focus Source # | |
Defined in Termonad.FocusList | |
unsafeGetFocus :: Focus -> Int Source #
Constructors
| FocusList | |
Fields
| |
Instances
invariantFL :: FocusList a -> Bool Source #
This is an invariant that the FocusList must always protect.
unsafeFLFromList :: Focus -> [a] -> FocusList a Source #
Unsafely create a FocusList. This does not check that the focus
actually exists in the list.
>>>let fl = unsafeFLFromList (Focus 1) [0..2]>>>debugFL fl"FocusList {focusListFocus = Focus 1, focusListLen = 3, focusList = fromList [(0,0),(1,1),(2,2)]}"
>>>let fl = unsafeFLFromList NoFocus []>>>debugFL fl"FocusList {focusListFocus = NoFocus, focusListLen = 0, focusList = fromList []}"
flFromList :: Focus -> [a] -> Maybe (FocusList a) Source #
Safely create a FocusList from a list.
>>>flFromList (Focus 1) ["cat","dog","goat"]Just (FocusList (Focus 1) ["cat","dog","goat"])
>>>flFromList NoFocus []Just (FocusList NoFocus [])
If the Focus is out of range for the list, then Nothing will be returned.
>>>flFromList (Focus (-1)) ["cat","dog","goat"]Nothing
>>>flFromList (Focus 3) ["cat","dog","goat"]Nothing
>>>flFromList NoFocus ["cat","dog","goat"]Nothing
singletonFL :: a -> FocusList a Source #
Create a FocusList with a single element.
>>>singletonFL "hello"FocusList (Focus 0) ["hello"]
appendFL :: FocusList a -> a -> FocusList a Source #
Append a value to the end of a FocusList.
This can be thought of as a "snoc" operation.
>>>appendFL emptyFL "hello"FocusList (Focus 0) ["hello"]
>>>appendFL (singletonFL "hello") "bye"FocusList (Focus 0) ["hello","bye"]
Appending a value to an empty FocusList is the same as using singletonFL.
appendFL emptyFL a == singletonFL a
appendSetFocusFL :: FocusList a -> a -> FocusList a Source #
A combination of appendFL and setFocusFL.
>>>let Just fl = flFromList (Focus 1) ["hello", "bye", "tree"]>>>appendSetFocusFL fl "pie"FocusList (Focus 3) ["hello","bye","tree","pie"]
(appendSetFocusFL fl a) ^. lensFocusListFocus /= fl ^. lensFocusListFocus
prependFL :: a -> FocusList a -> FocusList a Source #
Prepend a value to a FocusList.
This can be thought of as a "cons" operation.
>>>prependFL "hello" emptyFLFocusList (Focus 0) ["hello"]
The focus will be updated when prepending:
>>>prependFL "bye" (singletonFL "hello")FocusList (Focus 1) ["bye","hello"]
Prepending to a FocusList will always update the Focus:
(fl ^. lensFocusListFocus) < (prependFL a fl ^. lensFocusListFocus)
unsafeGetFLFocus :: FocusList a -> Int Source #
unsafeGetFLFocusItem :: FocusList a -> a Source #
getFLFocusItem :: FocusList a -> Maybe a Source #
unsafeInsertNewFL :: Int -> a -> FocusList a -> FocusList a Source #
Unsafely insert a new a in a FocusList. This sets the Int value to
a. The length of the FocusList will be increased by 1. The
FocusLists Focus is not changed.
If there is some value in the FocusList already at the Int, then it will
be overwritten. Also, the Int is not checked to make sure it is above 0.
This function is meant to be used after unsafeShiftUpFrom.
>>>let fl = unsafeShiftUpFrom 2 $ unsafeFLFromList (Focus 1) [0,1,200]>>>debugFL $ unsafeInsertNewFL 2 100 fl"FocusList {focusListFocus = Focus 1, focusListLen = 4, focusList = fromList [(0,0),(1,1),(2,100),(3,200)]}"
>>>let fl = unsafeFLFromList NoFocus []>>>debugFL $ unsafeInsertNewFL 0 100 fl"FocusList {focusListFocus = NoFocus, focusListLen = 1, focusList = fromList [(0,100)]}"
unsafeShiftUpFrom :: forall a. Int -> FocusList a -> FocusList a Source #
This unsafely shifts all values up in a FocusList starting at a given
index. It also updates the Focus of the FocusList if it has been
shifted. This does not change the length of the FocusList.
It does not check that the Int is greater than 0. It also does not check
that there is a Focus.
EXAMPLES
>>>let fl = unsafeShiftUpFrom 2 $ unsafeFLFromList (Focus 1) [0,1,200]>>>debugFL fl"FocusList {focusListFocus = Focus 1, focusListLen = 3, focusList = fromList [(0,0),(1,1),(3,200)]}"
>>>let fl = unsafeShiftUpFrom 1 $ unsafeFLFromList (Focus 1) [0,1,200]>>>debugFL fl"FocusList {focusListFocus = Focus 2, focusListLen = 3, focusList = fromList [(0,0),(2,1),(3,200)]}"
>>>let fl = unsafeShiftUpFrom 0 $ unsafeFLFromList (Focus 1) [0,1,200]>>>debugFL fl"FocusList {focusListFocus = Focus 2, focusListLen = 3, focusList = fromList [(1,0),(2,1),(3,200)]}"
>>>let fl = unsafeShiftUpFrom 0 $ unsafeFLFromList (Focus 1) [0,1,200]>>>debugFL fl"FocusList {focusListFocus = Focus 2, focusListLen = 3, focusList = fromList [(1,0),(2,1),(3,200)]}"
unsafeLookup :: Int -> IntMap a -> a Source #
Insert a new value into the FocusList. The Focus of the list is
changed appropriately.
>>>insertFL 0 "hello" emptyFLJust (FocusList (Focus 0) ["hello"])
>>>insertFL 0 "hello" (singletonFL "bye")Just (FocusList (Focus 1) ["hello","bye"])
>>>insertFL 1 "hello" (singletonFL "bye")Just (FocusList (Focus 0) ["bye","hello"])
This returns Nothing if the index at which to insert the new value is
either less than 0 or greater than the length of the list.
>>>insertFL 100 "hello" emptyFLNothing
>>>insertFL 100 "bye" (singletonFL "hello")Nothing
>>>insertFL (-1) "bye" (singletonFL "hello")Nothing
unsafeRemove :: Int -> FocusList a -> FocusList a Source #
Unsafely remove a value from a FocusList. It effectively leaves a hole
inside the FocusList. It updates the length of the FocusList.
This function does not check that a value actually exists in the
FocusList. It also does not update the Focus.
This function does update the length of the FocusList.
>>>debugFL $ unsafeRemove 1 $ unsafeFLFromList (Focus 0) [0..2]"FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(0,0),(2,2)]}"
>>>debugFL $ unsafeRemove 0 $ unsafeFLFromList (Focus 0) [0..2]"FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(1,1),(2,2)]}"
Trying to remove the last element is completely safe (unless, of course, it
is the Focus):
>>>debugFL $ unsafeRemove 2 $ unsafeFLFromList (Focus 2) [0..2]"FocusList {focusListFocus = Focus 2, focusListLen = 2, focusList = fromList [(0,0),(1,1)]}"
If this function is passed an empty FocusList, it will make the length -1.
>>>debugFL $ unsafeRemove 0 emptyFL"FocusList {focusListFocus = NoFocus, focusListLen = -1, focusList = fromList []}"
unsafeShiftDownFrom :: forall a. Int -> FocusList a -> FocusList a Source #
This shifts all the values down in a FocusList starting at a given
index. It does not change the Focus of the FocusList. It does not change the
length of the FocusList.
It does not check that shifting elements down will not overwrite other elements.
This function is meant to be called after unsafeRemove.
>>>let fl = unsafeRemove 1 $ unsafeFLFromList (Focus 0) [0..2]>>>debugFL $ unsafeShiftDownFrom 1 fl"FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(0,0),(1,2)]}"
>>>let fl = unsafeRemove 0 $ unsafeFLFromList (Focus 0) [0..2]>>>debugFL $ unsafeShiftDownFrom 0 fl"FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(0,1),(1,2)]}"
Trying to shift down from the last element after it has been removed is a no-op:
>>>let fl = unsafeRemove 2 $ unsafeFLFromList (Focus 0) [0..2]>>>debugFL $ unsafeShiftDownFrom 2 fl"FocusList {focusListFocus = Focus 0, focusListLen = 2, focusList = fromList [(0,0),(1,1)]}"
Arguments
| :: Int | Index of the element to remove from the |
| -> FocusList a | The |
| -> Maybe (FocusList a) |
Remove an element from a FocusList.
If the element to remove is not the Focus, then update the Focus
accordingly.
For example, if the Focus is on index 1, and we have removed index 2, then
the focus is not affected, so it is not changed.
>>>let focusList = unsafeFLFromList (Focus 1) ["cat","goat","dog","hello"]>>>removeFL 2 focusListJust (FocusList (Focus 1) ["cat","goat","hello"])
If the Focus is on index 2 and we have removed index 1, then the Focus
will be moved back one element to set to index 1.
>>>let focusList = unsafeFLFromList (Focus 2) ["cat","goat","dog","hello"]>>>removeFL 1 focusListJust (FocusList (Focus 1) ["cat","dog","hello"])
If we remove the Focus, then the next item is set to have the Focus.
>>>let focusList = unsafeFLFromList (Focus 0) ["cat","goat","dog","hello"]>>>removeFL 0 focusListJust (FocusList (Focus 0) ["goat","dog","hello"])
If the element to remove is the only element in the list, then the Focus
will be set to NoFocus.
>>>let focusList = unsafeFLFromList (Focus 0) ["hello"]>>>removeFL 0 focusListJust (FocusList NoFocus [])
If the Int for the index to remove is either less than 0 or greater then
the length of the list, then Nothing is returned.
>>>let focusList = unsafeFLFromList (Focus 0) ["hello"]>>>removeFL (-1) focusListNothing
>>>let focusList = unsafeFLFromList (Focus 1) ["hello","bye","cat"]>>>removeFL 3 focusListNothing
If the FocusList passed in is Empty, then Nothing is returned.
>>>removeFL 0 emptyFLNothing
indexOfFL :: Eq a => a -> FocusList a -> Maybe Int Source #
Find the index of the first element in the FocusList.
>>>let Just fl = flFromList (Focus 1) ["hello", "bye", "tree"]>>>indexOfFL "hello" flJust 0
If more than one element exists, then return the index of the first one.
>>>let Just fl = flFromList (Focus 1) ["dog", "cat", "cat"]>>>indexOfFL "cat" flJust 1
If the element doesn't exist, then return Nothing
>>>let Just fl = flFromList (Focus 1) ["foo", "bar", "baz"]>>>indexOfFL "hogehoge" flNothing
deleteFL :: forall a. Eq a => a -> FocusList a -> FocusList a Source #
Delete an element from a FocusList.
>>>let Just fl = flFromList (Focus 0) ["hello", "bye", "tree"]>>>deleteFL "bye" flFocusList (Focus 0) ["hello","tree"]
The focus will be updated if an item before it is deleted.
>>>let Just fl = flFromList (Focus 1) ["hello", "bye", "tree"]>>>deleteFL "hello" flFocusList (Focus 0) ["bye","tree"]
If there are multiple matching elements in the FocusList, remove them all.
>>>let Just fl = flFromList (Focus 0) ["hello", "bye", "bye"]>>>deleteFL "bye" flFocusList (Focus 0) ["hello"]
If there are no matching elements, return the original FocusList.
>>>let Just fl = flFromList (Focus 2) ["hello", "good", "bye"]>>>deleteFL "frog" flFocusList (Focus 2) ["hello","good","bye"]
setFocusFL :: Int -> FocusList a -> Maybe (FocusList a) Source #
Set the Focus for a FocusList.
This is just like updateFocusFL, but doesn't return the new focused item.
setFocusFL i fl == fmap snd (updateFocusFL i fl)
updateFocusFL :: Int -> FocusList a -> Maybe (a, FocusList a) Source #
Update the Focus for a FocusList and get the new focused element.
>>>updateFocusFL 1 =<< flFromList (Focus 2) ["hello","bye","dog","cat"]Just ("bye",FocusList (Focus 1) ["hello","bye","dog","cat"])
If the FocusList is empty, then return Nothing.
>>>updateFocusFL 1 emptyFLNothing
If the new focus is less than 0, or greater than or equal to the length of
the FocusList, then return Nothing.
>>>updateFocusFL (-1) =<< flFromList (Focus 2) ["hello","bye","dog","cat"]Nothing
>>>updateFocusFL 4 =<< flFromList (Focus 2) ["hello","bye","dog","cat"]Nothing
findFL :: (Int -> a -> Bool) -> FocusList a -> Maybe (Int, a) Source #
Find a value in a FocusList. Similar to Data.List..find
>>>let Just fl = flFromList (Focus 1) ["hello", "bye", "tree"]>>>findFL (\_ a -> a == "hello") flJust (0,"hello")
This will only find the first value.
>>>let Just fl = flFromList (Focus 0) ["hello", "bye", "bye"]>>>findFL (\_ a -> a == "bye") flJust (1,"bye")
If no values match the comparison, this will return Nothing.
>>>let Just fl = flFromList (Focus 1) ["hello", "bye", "parrot"]>>>findFL (\_ a -> a == "ball") flNothing
Arguments
| :: Show a | |
| => Int | Index of the item to move. |
| -> Int | New index for the item. |
| -> FocusList a | |
| -> Maybe (FocusList a) |
Move an existing item in a FocusList to a new index.
The Focus gets updated appropriately when moving items.
>>>let Just fl = flFromList (Focus 1) ["hello", "bye", "parrot"]>>>moveFromToFL 0 1 flJust (FocusList (Focus 0) ["bye","hello","parrot"])
The Focus may not get updated if it is not involved.
>>>let Just fl = flFromList (Focus 0) ["hello", "bye", "parrot"]>>>moveFromToFL 1 2 flJust (FocusList (Focus 0) ["hello","parrot","bye"])
If the element with the Focus is moved, then the Focus will be updated appropriately.
>>>let Just fl = flFromList (Focus 2) ["hello", "bye", "parrot"]>>>moveFromToFL 2 0 flJust (FocusList (Focus 0) ["parrot","hello","bye"])
If the index of the item to move is out bounds, then Nothing will be returned.
>>>let Just fl = flFromList (Focus 2) ["hello", "bye", "parrot"]>>>moveFromToFL 3 0 flNothing
If the new index is out of bounds, then Nothing wil be returned.
>>>let Just fl = flFromList (Focus 2) ["hello", "bye", "parrot"]>>>moveFromToFL 1 (-1) flNothing