Emptiable.empty to create an Empty Possibly stack.
A stack with just 1 single element.
import Emptiable
import Stack exposing (onTopLay)
Stack.only ":)"
--> Emptiable.empty |> onTopLay ":)"A stack from a top element and a List of elements below going down.
Take a tuple ( top, List belowElement )
from another source like turboMaCk/non-empty-list-alias
and convert it to an Emptiable (StackTopBelow top belowElement) never_
Use topDown if you don't already have a tuple to convert from.
Convert a List element to a Empty Possibly (Stacked element).
The Lists head becomes top, its tail is shoved down below.
import Possibly exposing (Possibly)
import Emptiable
import Stack exposing (topDown)
[] |> Stack.fromList
--> Emptiable.empty
[ "hello", "emptiness" ] |> Stack.fromList
--> topDown "hello" [ "emptiness" ]
--: Empty Possibly (Stacked String)When constructing from known elements, always prefer
import Stack exposing (topDown)
topDown "hello" [ "emptiness" ]Convert a String to a Emptiable (Stacked Char) Possibly.
The Strings head becomes top, its tail is shoved down below.
import Possibly exposing (Possibly)
import Emptiable
import Stack exposing (topDown)
"" |> Stack.fromText
--> Emptiable.empty
"hello" |> Stack.fromText
--> topDown 'h' [ 'e', 'l', 'l', 'o' ]
--: Emptiable (Stacked Char) PossiblyWhen constructing from known elements, always prefer
import Stack exposing (topDown)
onTopLay 'h' ("ello" |> Stack.fromText)The first value.
import Stack exposing (top, onTopLay)
Stack.only 3
|> onTopLay 2
|> top
--> 2How many element there are.
import Stack exposing (onTopLay)
Stack.only 3
|> onTopLay 2
|> Stack.length
--> 2The position of the element at the bottom.
import Stack exposing (onTopLay)
Stack.only 3
|> onTopLay 2
|> Stack.indexLast
--> 1Add an element to the front.
import Emptiable
import Stack exposing (topDown, onTopLay)
topDown 2 [ 3 ] |> onTopLay 1
--> topDown 1 [ 2, 3 ]
Emptiable.empty |> onTopLay 1
--> Stack.only 1Everything after the first value.
import Stack exposing (topDown, onTopLay, onTopStack, topRemove)
Stack.only 2
|> onTopLay 3
|> onTopStack (topDown 1 [ 0 ])
|> topRemove
--> topDown 0 [ 3, 2 ]
--: Emptiable (Stacked number_) PossiblyFlip the order of the elements.
import Stack exposing (topDown)
topDown "l" [ "i", "v", "e" ]
|> Stack.reverse
--> topDown "e" [ "v", "i", "l" ]Keep all filled elements
and drop all empty elements.
import Emptiable exposing (filled)
import Stack exposing (topDown)
topDown Emptiable.empty [ Emptiable.empty ]
|> Stack.fills
--> Emptiable.empty
topDown (filled 1) [ Emptiable.empty, filled 3 ]
|> Stack.fills
--> topDown 1 [ 3 ]As you can see, if only the top is fill a value, the result is non-empty.
Put the elements of a List on top.
import Stack exposing (topDown, onTopStack)
topDown 1 [ 2 ]
|> Stack.onTopGlue [ -1, 0 ]
--> topDown -1 [ 0, 1, 2 ]onTopGlue only when the piped stack food is already ... Never.
Glue a stack on top with
onTopStack takes on the possiblyOrNever type of the piped foodonTopStackAdapt takes on the possiblyOrNever type of the argumentGlue the elements of a stack to the end of the stack.
import Stack exposing (topDown, onTopStack)
topDown 1 [ 2 ]
|> onTopStack (topDown -1 [ 0 ])
--> topDown -1 [ 0, 1, 2 ]onTopStack takes on the possiblyOrNever type of the piped foodonTopStackAdapt takes on the possiblyOrNever type of the argumentGlue the elements of a ... Empty possiblyOrNever/Never Stack to the top of this Stack.
import Emptiable
import Stack exposing (topDown, onTopStack, onTopStackAdapt)
Emptiable.empty
|> onTopStackAdapt (topDown 1 [ 2 ])
|> onTopStack (topDown -2 [ -1, 0 ])
--> topDown -2 [ -1, 0, 1, 2 ]onTopStack takes on the possiblyOrNever type of the piped foodonTopStackAdapt takes on the possiblyOrNever type of the argumentGlue together a bunch of stacks.
import Emptiable
import Stack exposing (topDown)
topDown
(topDown 0 [ 1 ])
[ topDown 10 [ 11 ]
, Emptiable.empty
, topDown 20 [ 21, 22 ]
]
|> Stack.flatten
--> topDown 0 [ 1, 10, 11, 20, 21, 22 ]For this to return a non-empty stack, there must be a non-empty top stack.
Change every element based on its current value and { index }.
import Stack exposing (topDown)
topDown 1 [ 4, 9 ]
|> Stack.map (\_ -> negate)
--> topDown -1 [ -4, -9 ]
topDown 1 [ 2, 3, 4 ]
|> Stack.map (\{ index } n -> index * n)
--> topDown 0 [ 2, 6, 12 ]Combine its elements with elements of a given stack at the same location. If one stack is longer, the extra elements are dropped.
import Stack exposing (topDown)
topDown "alice" [ "bob", "chuck" ]
|> Stack.and (topDown 2 [ 5, 7, 8 ])
--> topDown ( "alice", 2 ) [ ( "bob", 5 ), ( "chuck", 7 ) ]
topDown 4 [ 5, 6 ]
|> Stack.and (topDown 1 [ 2, 3 ])
|> Stack.map (\_ ( n0, n1 ) -> n0 + n1)
--> topDown 5 [ 7, 9 ]Change the top element based on its current value.
Its type is allowed to change.
import Stack exposing (topDown, topMap)
topDown 1 [ 4, 9 ] |> topMap negate
--> topDown -1 [ 4, 9 ]Change every element below its top
based on their { index } in the whole stack and their current value.
Their type is allowed to change.
import Stack exposing (topDown, belowTopMap)
topDown 1 [ 4, 9 ]
|> belowTopMap (\_ -> negate)
--> topDown 1 [ -4, -9 ]Reduce in a direction.
import Linear exposing (DirectionLinear(..))
import Stack exposing (topDown)
topDown 'l' [ 'i', 'v', 'e' ]
|> Stack.foldFrom "" Down String.cons
--> "live"
topDown 'l' [ 'i', 'v', 'e' ]
|> Stack.foldFrom "" Up String.cons
--> "evil"Be aware:
Down = indexes decreasing, not: from the top downUp = indexes increasing, not: from the bottom up∑ Total every element number.
import Emptiable
topDown 1 [ 2, 3 ] |> Stack.sum
--> 6
topDown 1 (List.repeat 5 1) |> Stack.sum
--> 6
Emptiable.empty |> Stack.sum
--> 0Convert to a non-empty list tuple ( top, List belowElement )
to be used by another library.
import Stack exposing (topDown, toTopDown)
topDown "hi" [ "there", "👋" ]
|> toTopDown
--> ( "hi", [ "there", "👋" ] )Don't use toTopDown to destructure a stack.
Instead: Stack.top, Stack.topRemove
Convert it to a List.
import Stack exposing (topDown)
topDown 1 [ 7 ] |> Stack.toList
--> [ 1, 7 ]Don't try to use this prematurely. Keeping type information as long as possible is always a win.
The representation of a non-empty stack on the
Filledcase.top,topRemove,onTopLaytopMapareO(n)in arguments
Emptiable(StackFilled ...) Never→stackis non-empty:in results
Emptiable(StackFilled ...)PossiblyEmpty→ stack could be emptyWe can treat it like any
Emptiable:Most operations also allow a different type for the top element → see
StackTopBelow