ababup1192
5/20/2017 - 9:15 AM

zipper.elm

module Main exposing (..)

import Html exposing (text)
import MultiwayTree exposing (..)
import MultiwayTreeZipper exposing (..)
import Dict exposing (Dict)


type alias StrTree =
    Tree String


type alias KeyedStr =
    { key : Int, word : String }


type alias KeyedStrTree =
    Tree KeyedStr


type alias TreeZipper =
    Zipper KeyedStr


type alias Route =
    List Int


type alias BreadIndex =
    Dict Int Route



-- (&>) =
--   flip Maybe.map


main : Html.Html msg
main =
    text <| toString <| (flip Maybe.map createEmpZipper createBreadIndex)



-- (a, 0), (b, 1), (c, 4), (d, 2), (e, 3), (f, 5), (g, 6)
-- (0, []), (1, [0]), (2, [0, 0]), (3, [0, 1]), (4, [1]), (5, [1, 0]), (6, [1, 1])


base : StrTree
base =
    Tree "a"
        [ (Tree "b"
            [ Tree "d" [], Tree "e" [] ]
          )
        , (Tree "c"
            [ Tree "f" [], Tree "g" [] ]
          )
        ]


keyedStrTree : StrTree -> Maybe KeyedStrTree
keyedStrTree =
    indexedMap (\k w -> { key = k, word = w })


createEmpZipper : Maybe TreeZipper
createEmpZipper =
    Maybe.map (\t -> ( t, [] )) (base |> keyedStrTree)


createBreadIndex : TreeZipper -> ( TreeZipper, BreadIndex )
createBreadIndex (( tree, bc ) as tz) =
    let
        dict =
            createBreadIndex_ Dict.empty [] tree
    in
        ( tz, dict )


createBreadIndex_ : BreadIndex -> List Int -> KeyedStrTree -> BreadIndex
createBreadIndex_ dict cur tree =
    case tree of
        Tree v [] ->
            Dict.insert v.key cur dict

        Tree v forest ->
            let
                newDict =
                    Dict.insert v.key cur dict
            in
                createBreadIndex__ -1 cur newDict forest


createBreadIndex__ : Int -> List Int -> BreadIndex -> Forest KeyedStr -> BreadIndex
createBreadIndex__ idx parent dict forest =
    case forest of
        [] ->
            dict

        t :: ts ->
            case t of
                Tree v [] ->
                    let
                        curId =
                            idx + 1

                        cur =
                            parent ++ [ curId ]

                        newDict =
                            Dict.insert v.key cur dict
                    in
                        createBreadIndex__ (idx + 1) cur newDict ts

                Tree v tss ->
                    let
                        curId =
                            idx + 1

                        cur =
                            parent ++ [ curId ]

                        newDict =
                            Dict.insert v.key cur dict

                        curDict =
                            createBreadIndex__ (idx + 1) parent newDict ts

                        curcurDict =
                            createBreadIndex__ -1 parent newDict tss
                    in
                        Dict.union curDict curcurDict