turboMaCk/lazy-tree-with-zipper/2.0.0

NOTE: this package is not compatible with Elm 0.19.1

Lazy.LList

This module implements lazy construction of strict List. It is not Lazy List implementation and it has different characteristics. It's mostly intended for internal purposes of this library and is exposed just in case some additional user extensions will need it.

Types & Constructors

type alias LList a =
Lazy (List a)

LList uses lazy implementation and therefore can't be compared using ==

empty : LList a

Init empty LList.

toList empty
--> []
singleton : a -> LList a

Init singleton LList.

singleton "foo"
    |> toList
--> [ "foo" ]
llist : (a -> List b) -> a -> LList b

Init LList using constructor.

LList is init as a function from a -> List b. Evaluation of this function is lazy and happens in time when actuall value is needed, not when constructor is called.

For instance you can use some List constructor:

llist (List.range 0) 5
    |> toList
--> [ 0, 1, 2, 3, 4, 5 ]

Or use any other function you needList:

llist (List.filter <| \a -> a % 2 == 0) (List.range 0 10)
    |> toList
--> [ 0, 2, 4, 6, 8, 10 ]
isEmpty : LList a -> Bool

Check if LList is empty.

isEmpty empty
--> True


isEmpty (singleton "foo")
--> False


llist (List.filter <| \a -> a > 10) [ 1, 2, 3 ]
    |> isEmpty
--> True

This function forces evaluation.

fromList : List a -> LList a

Construct LList from List.

fromList [ "foo", "bar", "baz" ]
    |> toList
--> [ "foo", "bar", "baz" ]

Operations

cons : a -> LList a -> LList a

Add element to LList.

empty
    |> cons "bar"
    |> cons "foo"
    |> toList
--> [ "foo", "bar" ]

This function is performed lazily.

append : LList a -> LList a -> LList a

Append LList to LList.

append (singleton "foo") (fromList [ "bar", "baz" ])
    |> toList
--> [ "foo", "bar", "baz" ]

This function is performed lazily.

Query

isEmpty : LList a -> Bool

Check if LList is empty.

isEmpty empty
--> True


isEmpty (singleton "foo")
--> False


llist (List.filter <| \a -> a > 10) [ 1, 2, 3 ]
    |> isEmpty
--> True

This function forces evaluation.

toList : LList a -> List a

Build List from LList.

toList empty
--> []


toList <| llist (List.range 0) 2
--> [ 0, 1, 2 ]

This function forces evaluation.

tail : LList a -> Maybe (LList a)

Get first element from LList.

tail empty
--> Nothing


tail (singleton "foo")
    |> Maybe.map toList
--> Just []


llist (List.range 0) 2
    |> tail
    |> Maybe.map toList
--> Just [ 1, 2 ]

This function forces evaluation.

Transformations

map : (a -> b) -> LList a -> LList b

Map function over LList.

llist (List.range 0) 5
    |> map ((*) 2)
    |> toList
--> [ 0, 2, 4, 6, 8, 10 ]

This function is performed lazily.

map2 : (a -> b -> c) -> LList a -> LList b -> LList c

Map two functions over LList.

llist (List.range 0) 5
    |> map2 (+) (llist (List.range 0) 5)
    |> toList
--> [ 0, 2, 4, 6, 8, 10 ]

This function is performed lazily.

filter : (a -> Bool) -> LList a -> LList a

Filter LList.

(cons 1 <| cons 2 <| cons 3 empty)
    |> filter ((<) 1)
    |> toList
--> [ 2, 3 ]

This function is performed lazily.

filterMap : (a -> Maybe b) -> LList a -> LList b

Similar to List.filterMap but for LList.

(cons 1 <| cons 2 <| cons 3 empty)
    |> filterMap (\a -> if 1 < a then Just (2 * a) else Nothing)
    |> toList
--> [ 4, 6 ]

This function is performed lazily.

reverse : LList a -> LList a

Reverse LList.

fromList [ 1, 2, 3 ]
    |> reverse
    |> toList
--> [ 3, 2, 1 ]

This function is performed lazily.

sort : LList comparable -> LList comparable

Sort by for LList.

fromList [ 3, 1, 2 ]
    |> sort
    |> toList
--> [ 1, 2, 3 ]

This function is performed lazily.

sortBy : (a -> comparable) -> LList a -> LList a

Sort by for LList.

fromList [ 3, 1, 2 ]
    |> sortBy identity
    |> toList
--> [ 1, 2, 3 ]


fromList [ { val = "c"} , { val = "b"}, { val = "a"} ]
    |> sortBy .val
    |> toList
-->  [ { val = "a"}, { val = "b"}, { val = "c"} ]

This function is performed lazily.

sortWith : (a -> a -> Order) -> LList a -> LList a

Sort with for LList

flippedComparison : comparable -> comparable -> Order
flippedComparison a b =
    case Basics.compare a b of
        LT -> GT
        EQ -> EQ
        GT -> LT


llist (List.range 1) 5
    |> sortWith flippedComparison
    |> toList
--> [ 5, 4, 3, 2, 1 ]

This function is performed lazily.

foldr : (a -> b -> b) -> b -> LList a -> b

Same as List.foldr but for LLists.

llist (List.range 0) 5
    |> foldr (+) 0
--> 15


llist (List.range 0) 3
    |> foldr (::) []
--> [ 0, 1, 2, 3 ]

This function forces evaluation.

foldl : (a -> b -> b) -> b -> LList a -> b

Same as List.foldl but for LLists.

llist (List.range 0) 5
    |> foldl (+) 0
--> 15


llist (List.range 0) 3
    |> foldl (::) []
--> [ 3, 2, 1, 0 ]

This function forces evaluation.

lazyFoldr : (a -> Lazy b -> Lazy b) -> Lazy b -> LList a -> Lazy b

Lazy variant of foldr.

Works only with lazy values.

import Lazy


llist (List.range 0) 5
    |> lazyFoldr (\a -> Lazy.map ((+) a)) (Lazy.lazy <| always 0)
    |> Lazy.force
--> 15

This function is performed lazily.

lazyFoldl : (a -> Lazy b -> Lazy b) -> Lazy b -> LList a -> Lazy b

Lazy variant of foldl.

Works only with lazy values.

import Lazy


llist (List.range 0) 5
    |> lazyFoldl (\a -> Lazy.map ((+) a)) (Lazy.lazy <| always 0)
    |> Lazy.force
--> 15

This function is performed lazily.

concat : LList (LList a) -> LList a

Flatten LList.

fromList [ singleton "foo", cons "bar" <| singleton "baz" ]
   |> concat
   |> toList
--> [ "foo", "bar", "baz" ]

This function is performed lazily.

andThen : (a -> LList b) -> LList a -> LList b

Map LList construction over LList.

cons "foo" (cons "bar" <| singleton "baz")
    |> andThen (\a -> cons a <| singleton (a ++ " fighter" ))
    |> toList
--> [ "foo", "foo fighter", "bar", "bar fighter", "baz", "baz fighter" ]

This function is performed lazily.