Skip to content

Instantly share code, notes, and snippets.

@coodoo
Created October 27, 2017 06:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coodoo/7ea1597457fb73fd44418a13fb26520e to your computer and use it in GitHub Desktop.
Save coodoo/7ea1597457fb73fd44418a13fb26520e to your computer and use it in GitHub Desktop.
Convert list to tree using State monad, in a suck less manner ๐Ÿ˜…
module Bar () where
import Data.Maybe
import Control.Monad.State
import qualified Data.Map as M
data Item = Item {
sId :: String,
pId :: String,
value :: [Char],
children :: [String]
} deriving (Show)
list :: [Item]
list = [
Item { sId="1", pId="0", value="1", children=[] },
Item { sId="1-1", pId="1", value="1-1", children=[] },
Item { sId="1-2", pId="1", value="1-2", children=[] },
Item { sId="2", pId="0", value="2", children=[] },
Item { sId="2-1", pId="2", value="2-1", children=[] },
Item { sId="2-2", pId="2", value="2-2", children=[] }]
type Table = M.Map String Item
rootNode = Item { sId="0", pId="-1", value="root node", children=[] }
initTable = M.insert "0" rootNode M.empty
-- ๅ…ˆๅฐ‡ list ่ฝ‰ๆˆ map
toTable :: [Item] -> Table
toTable xs = foldl (\acc x -> M.insert (sId x) x acc ) initTable xs
entry = evalState (numberTree list) (toTable list)
test1 = mapM_ print entry -- ๅฐๅ‡บ table ๅ…งๅฎน
test2 = fromJust $ M.lookup "2" entry -- ๆŸฅๆ‰พ "2" ้€™ๅ€‹ item ็œ‹ๅฎƒ children = ["2-1","2-2"]
-- ้€ฒๅ…ฅ้ปž --
numberTree :: [Item] -> State Table Table
numberTree (x:xs) =
numberNode x
>>= \z -> if (length xs) /= 0 then (numberTree xs) else get
>>= \table -> return table
where
numberNode :: Item -> State Table ()
numberNode x = do
table <- get
newTable <- return (nNode x table) -- a == s
put newTable
return ()
nNode :: Item -> Table -> Table
nNode x table =
M.adjust
(\item -> item { children = (children item) ++ [(sId x)] })
(pId x)
table
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment