Code Monkey home page Code Monkey logo

elm-pivot's Issues

Discrepancy between `mapCLR_` and `mapR_`.

See example below. For readability, list notation with center denoted by *s is used for a pivot.

mapR_ (List.take 1) [1,2,*3*,4,5] == [1,2,*3*,5]
mapCLR_ identity identity (List.take 1) [1,2,*3*,4,5] == [1,2,*3*,4]

Awkward implementation and lack of testing are to blame.

elm-pivot/Pivot/Map.elm

Lines 70 to 73 in cee1b98

mapR_ : (List a -> List a) -> Pivot a -> Pivot a
mapR_ f =
mapL_ f
|> mirror

Documentation makes matters worse, as it hints that these two applications above should have the same result.

elm-pivot/Pivot.elm

Lines 530 to 532 in cee1b98

{-| See `mapCLR_`.
-}
mapR_ : (List a -> List a) -> Pivot a -> Pivot a

As for fixing, the following works:

mapR_ = mapCLR_ identity identity

Still, it could be optimized, as mapCLR_ internally reverses the left side twice.

Indexed Maps

indexedMapCLR would be really nice right about now in my project. ...Or at least an easy way to zip a tuple of ( Int, a ).

Optimize out abstractions

It appears that the uses of abstractions such as function calls, the function mirror, etc impact performance even though they are functionally equivalent to other more direct implementations (see discussion in #13).

`setR` reverses its argument

setR reverses its argument. For example, setR [4, 5, 6] [ 1 * 2 * 3 ] == [ 1 * 2 * 6 5 4 ].

Would you like me to submit a fix?

Attached: a property test suite that helped me diagnose the issue

module Tests.Pivot exposing (pivotTests)

import Expect
import Fuzz exposing (Fuzzer)
import Pivot exposing (Pivot)
import Test exposing (Test, describe)


genPivotInt : Fuzzer (Pivot Int)
genPivotInt =
    Fuzz.map3
        (\a b c -> Pivot.singleton b |> Pivot.setL a |> Pivot.setR c)
        (Fuzz.list Fuzz.int)
        Fuzz.int
        (Fuzz.list Fuzz.int)


genListInt : Fuzzer (List Int)
genListInt =
    Fuzz.list Fuzz.int


pivotTests : Test
pivotTests =
    describe "pivot"
        [ Test.fuzz genPivotInt "setL (getL a) == a" <|
            \pivot ->
                Pivot.setL (Pivot.getL pivot) pivot
                    |> Expect.equal pivot
        , Test.fuzz2 genListInt genPivotInt "getL (setL l a) == l" <|
            \list pivot ->
                Pivot.getL (Pivot.setL list pivot)
                    |> Expect.equal list
        , Test.fuzz genPivotInt "setR (getR a) == a" <|
            \pivot ->
                Pivot.setR (Pivot.getR pivot) pivot
                    |> Expect.equal pivot
        , Test.fuzz2 genListInt genPivotInt "getR (setR l a) == l" <|
            \list pivot ->
                Pivot.getR (Pivot.setR list pivot)
                    |> Expect.equal list
        , Test.fuzz3 Fuzz.int genListInt genPivotInt "goR (setR (x :: xs) a) == Just (setR xs (appendGoR x a))" <|
            \x xs pivot ->
                Pivot.goR (Pivot.setR (x :: xs) pivot)
                    |> Expect.equal (Just (Pivot.setR xs (Pivot.appendGoR x pivot)))

        ]

Should we have a relative version of `zip`?

This is zip as it is now:

elm-pivot/Pivot/Map.elm

Lines 81 to 96 in cee1b98

zip : Pivot a -> Pivot ( Int, a )
zip pvt =
let
n =
lengthL pvt
onC =
(,) n
onL =
List.indexedMap (,)
onR =
List.indexedMap ((+) (n + 1) >> (,))
in
mapCLR_ onC onL onR pvt

It indexes the pivot like a list, without any regard to where the center is.
It may be beneficial to have a relative version.

 zipRelative : Pivot a -> Pivot ( Int, a ) 
 zipRelative pvt = 
     let 
         onC = 
             \x -> (0,x) 
  
         onL = 
             List.indexedMap (\i x -> (-1 - i,x)) 
  
         onR = 
             List.indexedMap (\i x -> (i + 1, x)) 
     in 
mapCLR_ onC onL onR pvt 

For example, a situation where one knows their pivot is going to get jumbled, and would like to retain their current positions afterwards.

In such a case we could also change the name of zip to zipAbsolute, leaving less room for confusion. To increase uniformity, we could further replace goTo by goAbsolute; and goBy by goRelative.

In fact, why is it called zip in the first place? index is better...

Test coverage

Tests should cover the entire library.

  • Every function should be tested against a typical example and all edge examples.
  • Every functional identity mentioned in the documentation should be fuzzy tested.

Upgrade to Elm v0.18

The only changes I see to be had are removing ' primes from variables. I'd also suggest renaming pure to singleton to match other Elm libraries.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.