How to improve calculation on shortest distance more idiomatically in Haskell? -


i've tried write calculation on shortest distance between 2 graph nodes according dijkstra's algorithm below, 2 things in code rather imperative , tedious:

  • explicitly passing parameters mutated states in order reuse them later;
  • heavily using conditional branch.

so i'd learn how improve in more idiomatic way of haskell you. lot in advance.

import qualified data.set set (size, insert) import data.set (set, empty, notmember) import qualified data.map map (size, insert, lookup) import data.map (map, fromlist) import data.maybe (fromjust)  {-   g: graph map, every edge weighs 1 simplicity.   s: source vertex   t: target vertex   c: current vertex   a: adjacent vertex   as: adjacent vertex list   v: visited vertex set   d: shortest distance map -}  -- purposely skipped explicit type signature make short below,  caltotarget g t c v d    | set.size v < map.size g - 1        && c /= t        && notmember c v        = calfromadj (lookup' c g) g t c v d    | otherwise = d   calfromadj []       _ _ _ _ d = d  calfromadj (a : as) g t c v d = calfromadj g t c v $    caltotarget g t (set.insert c v) (calfromcurrent (a : as) c v d)  calfromcurrent []       _ _ d = d  calfromcurrent (a : as) c v d    | notmember v = calfromcurrent c v $       map.insert (min (lookup' d) (lookup' c d + 1)) d   | otherwise = calfromcurrent c v d  lookup' k m = fromjust $ map.lookup k m  -- test below,  {-   a-s---b-c      \  |\       \ | \        \|  \         d-e-t-f -}  g = fromlist   [     ("a", ["s"]),     ("s", ["a", "b", "d"]),     ("b", ["s", "c", "d", "t"]),     ("c", ["b"]),     ("d", ["s", "b", "e"]),     ("e", ["d", "t"]),     ("t", ["b", "e", "f"]),     ("f", ["t"])   ]  infinity = 99  d = fromlist   [     ("a", infinity),     ("s", infinity),     ("b", infinity),     ("c", infinity),     ("d", infinity),     ("e", infinity),     ("t", infinity),     ("f", infinity)   ]  v = empty  s = "s" t = "t"  -- shortest distance equal 2 "s" "t" below,  main =   print . lookup' t . caltotarget g t s v $ map.insert s 0 d 


Comments

Popular posts from this blog

tcpdump - How to check if server received packet (acknowledged) -