Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added insertAt, rewrote splitAt to use new helper #30

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions src/List/Extra.elm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module List.Extra
, updateIf
, updateAt
, updateIfIndex
, insertAt
, singleton
, removeAt
, filterNot
Expand Down Expand Up @@ -81,7 +82,7 @@ module List.Extra
{-| Convenience functions for working with List

# Basics
@docs last, init, getAt, (!!), uncons, maximumBy, minimumBy, andMap, andThen, takeWhile, dropWhile, unique, uniqueBy, allDifferent, allDifferentBy, replaceIf, setAt, remove, updateIf, updateAt, updateIfIndex, singleton, removeAt, filterNot, swapAt, stableSortWith
@docs last, init, getAt, (!!), uncons, maximumBy, minimumBy, andMap, andThen, takeWhile, dropWhile, unique, uniqueBy, allDifferent, allDifferentBy, replaceIf, setAt, remove, updateIf, updateAt, updateIfIndex, insertAt, singleton, removeAt, filterNot, swapAt, stableSortWith

# List transformations
@docs intercalate, transpose, subsequences, permutations, interweave
Expand Down Expand Up @@ -487,6 +488,15 @@ updateIfIndex predicate update list =
list


{-| Insert an element at given index
-}
insertAt : Int -> a -> List a -> List a
insertAt index value list =
splitAtWithReversedInit index [] list
|> Tuple.mapSecond ((::) value)
|> uncurry appendUsingReversedInit


{-| Remove the first occurrence of a value from a list.
-}
remove : a -> List a -> List a
Expand Down Expand Up @@ -886,7 +896,8 @@ unfoldr f seed =
-}
splitAt : Int -> List a -> ( List a, List a )
splitAt n xs =
( take n xs, drop n xs )
splitAtWithReversedInit n [] xs
|> Tuple.mapFirst List.reverse


{-| Take elements from the right, while predicate still holds.
Expand Down Expand Up @@ -1271,3 +1282,30 @@ greedyGroupsOfWithStep size step xs =
group :: greedyGroupsOfWithStep size step xs_
else
[]



-- Helpers


splitAtWithReversedInit : Int -> List a -> List a -> ( List a, List a )
splitAtWithReversedInit n reversedInit tail =
if n <= 0 then
( reversedInit, tail )
else
case tail of
head :: nextTail ->
splitAtWithReversedInit (n - 1) (head :: reversedInit) nextTail

[] ->
( reversedInit, tail )


appendUsingReversedInit : List a -> List a -> List a
appendUsingReversedInit reversedInit tail =
case reversedInit of
head :: remainingReversedInit ->
appendUsingReversedInit remainingReversedInit (head :: tail)

[] ->
tail
35 changes: 32 additions & 3 deletions tests/Tests.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ module Tests exposing (..)

import Test exposing (..)
import Expect
import Fuzz exposing (list, int, tuple3)
import Fuzz exposing (char, list, int, intRange, tuple3)
import List exposing (map, range)
import Random
import Tuple exposing (first)
import List.Extra exposing (..)

Expand Down Expand Up @@ -89,6 +90,32 @@ all =
\() ->
Expect.equal (findIndices (\x -> x % 2 == 0) [ 1, 2, 4 ]) [ 1, 2 ]
]
, describe "insertAt" <|
[ fuzz
(list char |> Fuzz.andThen (\xs -> tuple3 ( intRange 0 (List.length xs), char, Fuzz.constant xs )))
"0 <= index <= length"
(\( n, x, xs ) ->
Expect.equal
(List.take n xs ++ (x :: List.drop n xs))
(insertAt n x xs)
)
, fuzz
(tuple3 ( intRange Random.minInt -1, char, list char ))
"index < 0"
(\( n, x, xs ) ->
Expect.equal
(x :: xs)
(insertAt n x xs)
)
, fuzz
(list char |> Fuzz.andThen (\xs -> tuple3 ( intRange (List.length xs + 1) Random.maxInt, char, Fuzz.constant xs )))
"index > length"
(\( n, x, xs ) ->
Expect.equal
(xs ++ [ x ])
(insertAt n x xs)
)
]
, describe "intercalate" <|
[ test "computes example" <|
\() ->
Expand Down Expand Up @@ -370,7 +397,8 @@ all =
\listA listB ->
not (List.Extra.isPrefixOf listA listB)
|| not (List.Extra.isPrefixOf listB listA)
|| listA == listB
|| listA
== listB
|> Expect.true "Expected exactly one to be prefix of the other."
, fuzz3 (list int) (list int) (list int) "transitivity" <|
\listA listB listC ->
Expand All @@ -392,7 +420,8 @@ all =
\listA listB ->
not (List.Extra.isSuffixOf listA listB)
|| not (List.Extra.isSuffixOf listB listA)
|| listA == listB
|| listA
== listB
|> Expect.true "Expected exactly one to be suffix of the other."
, fuzz3 (list int) (list int) (list int) "transitivity" <|
\listA listB listC ->
Expand Down