{- Lazy Positions Function CSci 450/503, Fall 2016 H. Conrad Cunningham 2016-11-27: adapted strict version to use Lazy.List library 2016-11-29: updated comments about installation This version uses the LazyList data structure instead of the normal strict (nonlazy) list. The LazyList only evaluates elements of the data structure when needed. To use, install non-core packages elm-package install elm-lang/lazy elm-pacakge install elm-community/ -} import Html exposing (..) import Lazy -- community contributed library on Elm site import Lazy.List -- community contributed library on Elm site -- Function positions takes a list xs and a value x and returns the -- lazy list of indexes at which x occurs in xs. This functions uses -- the important higher order library functions map and filter (called -- keepIf in the Lazy.List library). positions : List a -> a -> Lazy.List.LazyList Int positions xs x = Lazy.List.map Tuple.first (Lazy.List.keepIf (((==) x) << Tuple.second) (Lazy.List.zip Lazy.List.numbers (Lazy.List.fromList xs))) -- Function position takes a list xs and a value x and returns x's -- index in xs. It takes the head from the list returned by -- positions. This value is a Maybe; by using withDefault, it converts -- the returned Maybe value to 0. position : List a -> a -> Int position xs x = Maybe.withDefault 0 (Lazy.List.head (positions xs x)) -- Simple Display Functions newline = br [] [] displayLines : List String -> List (Html msg) displayLines ss = case ss of [] -> [] x :: xs -> text x :: newline :: displayLines xs display : List String -> Html msg display ls = p [] (displayLines ls) -- Some testing names = ["Adam","Eve","Cain","Abel","Seth", "Adam"] pos1 = positions names "Adam" pos2 = positions names "Elijah" pos3 = position names "Cain" main = display [ "Begin!" , "names == [Adam, Eve, Cain, Abel, Seth, Adam]" , "positions names Adam == " ++ toString pos1 , "positions names Adam == " ++ toString (Lazy.List.toList pos1) , "positions names Elijah == " ++ toString pos2 , "positions names Elijah == " ++ toString (Lazy.List.toList pos2) , "position names Cain == " ++ toString pos3 , "End!" ]