A linear structure with a cursor pointing to some specific element. Tapes cannot be empty.
Create a tape from the left, head, and right parts.
The tape is conceptually equivalent to the list left ++ [head] ++ right
and has a cursor that points to the tape head.
create [ "a", "b" ] "c" [ "d", "e" ]
|> show identity
--> "[ a, b, => c, d, e ]"Try to create tape from List. Empty lists return Nothing.
(fromList [ 1, 2, 3 ]
|> Maybe.map toList)
--> Just [ 1, 2, 3 ]Create a tape from List or a singleton tape with the given default value.
fromListOrDefault 0 [ 1, 2, 3 ]
|> toList
--> [ 1, 2, 3 ]Construct tape from left and right tails.
fromParts (tail Left tape) (head tape) (tail Right tape) ==> tapeCreate a tape with n copies of a value and tries to place m of them before the head.
repeat 0 behaves similarly to List.repeat, creating a tape with n elements
pointing to the first element.
Empty negative n are ignored, returning a tape with a single element.
repeat 2 5 "a"
|> show identity
--> "[ a, a, => a, a, a ]"Create a tape of numbers, every element increasing by one.
The arguments are the lowest and highest numbers that should be on the tape.
range 0 5
|> toList
--> [ 0, 1, 2, 3, 4, 5 ]Write element to the tape's current position.
create ["a", "b"] "c" ["d", "e"]
|> write "changed"
|> show identity
--> "[ a, b, => changed, d, e ]"Advance tape to the last element
create ["a", "b"] "c" ["d", "e"]
|> advance
|> show identity
--> "[ a, b, c, d, => e ]"Rewind tape so the head points to the first element
create ["a", "b"] "c" ["d", "e"]
|> rewind
|> show identity
--> "[ => a, b, c, d, e ]"Move at most n positions to the left.
Negative steps move to the right.
create ["a", "b", "c"] "d" ["e"]
|> left 2
|> show identity
--> "[ a, => b, c, d, e ]"Move at most n positions to the right.
Negative values move to the left.
create ["a", "b", "c"] "d" ["e"]
|> right 2
|> show identity
--> "[ a, b, c, d, => e ]"An alias to left 1 that is more idiomatic when using the tape as a history container.
create ["a", "b", "c"] "d" ["e"]
|> undo
|> show identity
--> "[ a, b, => c, d, e ]"An alias to right 1 that is more idiomatic when using the tape as a history container.
create ["a", "b", "c"] "d" ["e"]
|> redo
|> show identity
--> "[ a, b, c, d, => e ]"Declare how to move in the tape.
Move head to the left according to strategy
create ["a", "b"] "c" ["d", "e"]
|> leftWith (Cycle 3)
|> show identity
--> "[ a, b, c, d, => e ]"
create ["a", "b"] "c" ["d", "e"]
|> leftWith (Default ("?", 4))
|> show identity
--> "[ => ?, ?, a, b, c, d, e ]"
create ["a", "b"] "c" ["d", "e"]
|> leftWith (Condition ((/=) "b"))
|> show identity
--> "[ a, => b, c, d, e ]"
create ["a", "b"] "cc" ["d", "e"]
|> leftWith (Carry 2)
|> show identity
--> "[ => cc, a, b, d, e ]"Move head to the right according to strategy
create ["a", "b"] "c" ["d", "e"]
|> rightWith (Cycle 3)
|> show identity
--> "[ => a, b, c, d, e ]"
create ["a", "b"] "c" ["d", "e"]
|> rightWith (Default ("?", 4))
|> show identity
--> "[ a, b, c, d, e, ?, => ? ]"
create ["a", "b"] "c" ["d", "e"]
|> rightWith (Condition ((/=) "b"))
|> show identity
--> "[ a, b, c, d, => e ]"
create ["a", "b"] "c" ["d", "e"]
|> rightWith (Carry 2)
|> show identity
--> "[ a, b, d, e, => c ]"Try to move to the left.
Return Nothing if the tape would overflow on the leftmost position.
create ["a"] "b" ["c", "d", "e"]
|> tryLeft 2
--> NothingTry to move to the right.
Return Nothing if the tape would overflow on the rightmost position.
create ["a", "b"] "c" ["d"]
|> tryRight 2
--> NothingPush element to the left of the current head and move the cursor to it.
create ["a", "b"] "c" ["d", "e"]
|> pushLeft "changed"
|> show identity
--> "[ a, b, => changed, c, d, e ]"Push element to the right of the current head and move the cursor to it.
create ["a", "b"] "c" ["d", "e"]
|> pushRight "changed"
|> show identity
--> "[ a, b, c, => changed, d, e ]"Apply a function to every element of a tape.
create ["a", "b"] "c" ["d", "e"]
|> map String.toUpper
|> show identity
--> "[ A, B, => C, D, E ]"Combine two tapes with function.
It keeps the smallest left and right tails of each tape.
(map2 (++)
(create ["a", "b"] "c" ["d", "e"])
(repeat 1 5 "x")
)
|> show identity
--> "[ bx, => cx, dx, ex ]"Generalize map for 3 tapes
Generalize map for 4 tapes
Generalize map for 5 tapes
Same as map but the function is also applied to the index of each element.
The head has an index of zero and the left hand side of the tape is indexed with negative numbers.
create ["a", "b"] "c" ["d", "e"]
|> indexedMap (\i x -> String.fromInt i ++ x)
|> show identity
--> "[ -2a, -1b, => 0c, 1d, 2e ]"Similar to indexedMap, but uses the position of each element, which is equivalent to the index of a rewinded tape.
create ["a", "b"] "c" ["d", "e"]
|> positionalMap (\i x -> String.fromInt i ++ x)
|> show identity
--> "[ 0a, 1b, => 2c, 3d, 4e ]"Flip a tape around the head.
create ["a", "b"] "c" ["d", "e"]
|> reverse
|> show identity
--> "[ e, d, => c, b, a ]"Sort values from lowest to highest
Head moves to keep track of current element.
create ["d"] "c" ["a", "e", "b"]
|> sort
|> show identity
--> "[ a, b, => c, d, e ]"Sort values by a derived property.
Head moves to keep track of current element.
create ["d"] "cc" ["a", "eee", "bb"]
|> sortBy String.length
|> show identity
--> "[ d, a, => cc, bb, eee ]"Sort values with a custom comparison function.
Head moves to keep track of current element.
Places the given value between all members of the given tape.
create ["a", "b"] "c" ["d", "e"]
|> intersperse "x"
|> show identity
--> "[ a, x, b, x, => c, x, d, x, e ]"The direction enum selects parts of the tape that shall be extracted/modified.
Each function might interpret each direction slightly differently. Check the documentation for more details.
Select parts of a tape and return it as a list
create ["a", "b"] "c" ["d", "e"]
|> select All
--> [ "a", "b", "c", "d", "e" ]
create ["a", "b"] "c" ["d", "e"]
|> select Left
--> [ "a", "b", "c" ]
create ["a", "b"] "c" ["d", "e"]
|> select Backwards
--> [ "c", "b", "a" ]
create ["a", "b"] "c" ["d", "e"]
|> select Head
--> [ "c" ]
create ["a", "b"] "c" ["d", "e"]
|> select Tails
--> [ "a", "b", "d", "e" ]A partial map on the tape, preserving the types of elements.
We can specify a direction to update from the head
create ["a", "b"] "c" ["d", "e"]
|> update Right String.toUpper
|> show identity
--> "[ a, b, => C, D, E ]"The direction can be one of the following:
- `Left` - only the left part is modified, including the head.
- `Right` - only the right part is modified, including the head.
- `LeftTail` - only the left part is modified, excluding the head.
- `RightTail` - only the right part is modified, excluding the head.
- `Backwards` - same as Left.
- `BackwardsTail` - same as LeftTail.
- `Head` - only the head is modified.
- `Tails` - modify everything exept the head.
- `InsideOut` - like All.
- `All` - all elements are modified.Filter the given selection of tape with predicate.
Filter never removes the head, which makes filter Head a no-op and
filter DirectoinTail and filter Direction equivalent.
If you want to filter the head, convert to a list before
Decompose a tape of tuples into a tuple of tapes.
create [("a", 1), ("b", 2)] ("c", 3) [("d", 4), ("e", 5)]
|> unzip
|> Tuple.mapBoth (show identity) (show String.fromInt)
--> ( "[ a, b, => c, d, e ]", "[ 1, 2, => 3, 4, 5 ]" )Separate the list in the (left, head, tail) parts.
The parts can be assembled back together with create left head tail
Converts tape to list
create ["a", "b"] "c" ["d", "e"]
|> toList
--> ["a", "b", "c", "d", "e"]Reduce a tape from the right.
It has the same effect as reducing the equivalent list.
create ["a", "b"] "c" ["d", "e"]
|> foldr (++) "$"
--> "abcde$"Reduce a tape from the left.
It has the same effect as reducing the equivalent list.
create ["a", "b"] "c" ["d", "e"]
|> foldl (++) "$"
--> "edcba$"Reduce tape applying binary operator.
Similar to a left fold, but it does not require an initial accumulator.
create ["a", "b"] "c" ["d", "e"]
|> reduce (++)
--> "abcde"
create [] "c" ["d", "e"]
|> reduce (++)
--> "cde"Determine if all elements satisfy some test.
create ["a", "b"] "c" ["d", "e"]
|> all (\x -> String.length x < 2)
--> TrueDetermine if any element satisfy some test.
create ["a", "b"] "c" ["d", "e"]
|> any (\x -> x == "e")
--> TrueDetermine the length of a tape.
create ["a", "b"] "c" ["d", "e"]
|> length
--> 5Determine the position of head.
Position corresponds to the number of steps we must move right from a rewinded tape.
create ["a", "b"] "c" ["d", "e"]
|> position
--> 2Figure out whether a tape contains a value.
create ["a", "b"] "c" ["d", "e"]
|> member "b"
--> TrueTrue if tape has no elements to the left o head
True if tape has no elements to the right o head
Base iterator type