{- Positions Function CSci 450/503, Fall 2016 H. Conrad Cunningham 2016-11-26: original version 2016-11-27: revised to use composition -} import Html exposing (..) -- Function zip is a typical function (e.g., in Haskell) that does not -- seem to be defined in the current Elm library. zip takes two lists and -- returns the corresponding list of pairs. zip = List.map2 (,) -- Function secondis takes a value x and a pair t and returns True if -- and only if the second component of t is x. -- 11-27: REPLACED secondis with (((==) x) << Tuple.second). This is -- the compositon of the one-argument function Tuple.second and ((==) -- x), which partially applies the equality function (==) to its left -- operand x. secondis : b -> (a,b) -> Bool secondis x t = x == Tuple.second t -- Function positions takes a list xs and a value x and returns the -- list of indexes at which x occurs in xs. This functions uses the -- important higher order library functions map and filter. (I -- converted this from a Haskell comprehension as I was learning Elm. -- There may be better ways of implementing this. One approach would -- be to use a let expression to define the complext parts of the -- expression into smaller steps. positions : List a -> a -> List Int positions xs x = List.map Tuple.first (List.filter (((==) x) << Tuple.second) -- REPLACED: (secondis x) (zip (List.range 1 (List.length xs)) 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 (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 Elijah == " ++ toString pos2 , "position names Cain == " ++ toString pos3 , "End!" ]