core icon indicating copy to clipboard operation
core copied to clipboard

Dict.get works unreliably when keys are lists and --optimize is enabled

Open peterszerzo opened this issue 6 years ago • 0 comments

I am using the Dict (List Int) a data type in a project, and I came across cases when Dict.get doesn't find entries when --optimize is enabled. I was not able to isolate this into an SSCCE (it seems to only show up after the dictionary is manipulated throughout an algorithm), so attaching screenshots from the project instead:

If I use Dict.get when accessing coordinates for tree nodes, the package draws the following incomplete tree (entry with the key of [] is not found): screen shot 2019-01-21 at 2 32 49 pm

However, if I replace Dict.get with a method where I'm inefficiently finding the key where the lists-of-ints match up:

-- This is used instead of `Dict.get`
dictGetWithListKeys : List comparable -> Dict.Dict (List comparable) a -> Maybe a
dictGetWithListKeys key dict =
    Dict.toList dict
        |> List.filter (\( currentKey, currentValue ) -> areListsEqual key currentKey)
        |> List.head
        |> Maybe.map Tuple.second

areListsEqual : List comparable -> List comparable -> Bool
areListsEqual list1 list2 =
    case ( list1, list2 ) of
        ( [], [] ) ->
            True

        ( [], _ :: _ ) ->
            False

        ( _ :: _, [] ) ->
            False

        ( head1 :: tail1, head2 :: tail2 ) ->
            if head1 == head2 then
                areListsEqual tail1 tail2

            else
                False

then I get the expected result:

screen shot 2019-01-21 at 2 33 08 pm

I realize that this is an incredibly obscure edge case, but it took me several months to narrow it down to Dict.get, during which time I couldn't use the optimize flag for a large app. Could save someone else some time on this in the future, even if it's just documented here.

peterszerzo avatar Jan 21 '19 19:01 peterszerzo