neighborNodes :: Input a => a -> StGNG a (Node a, Node a)
neighborNodes input = do
    gng <- State.get
    f (Map.elems (gng^.nodes)) input nothing nothing
  where
    f _      _ (Nothing, _)    (Just _, _) = error "not reached"
    f []     _ (Just n1, _)    (Just n2, _) = return (n1, n2)
    f []     i m1@(Just _, _)  (Nothing, _) =
        newNode i >>= \n -> f [] i m1 (Just n, infinity)
    f []     i m1@(Nothing, _) _ =
        newNode i >>= \n -> f [] i (Just n, infinity) m1
    f (n:ns) i m1@(_, mx1)     m2@(_, mx2) = if d < mx1
        then f ns i (Just n, d) m1
        else if d < mx2
            then f ns i m1 (Just n, d)
            else f ns i m1 m2
      where
        d = dist i (n^.value)

    nothing = (Nothing, infinity)
    infinity = 1 / 0 :: Double
neighborNodes :: Input a => a -> StGNG a (Node a, Node a)
neighborNodes input = do
    gng <- State.get
    f (Map.elems (gng^.nodes)) input nothing nothing
  where
    f _      _ (Nothing, _)    (Just _, _) = error "not reached"
    f []     _ (Just n1, _)    (Just n2, _) = return (n1, n2)
    f []     i m1@(Just _, _)  (Nothing, _) =
        newNode i >>= \n -> f [] i m1 (Just n, infinity)
    f []     i m1@(Nothing, _) _ =
        newNode i >>= \n -> f [] i (Just n, infinity) m1
    f (n:ns) i m1@(_, mx1)     m2@(_, mx2) = if d < mx1
        then f ns i (Just n, d) m1
        else if d < mx2
            then f ns i m1 (Just n, d)
            else f ns i m1 m2
      where
        d = dist i (n^.value)

    nothing = (Nothing, infinity)
    infinity = 1 / 0 :: Double
neighborNodes input = do
    gng <- State.get
    f (Map.elems (gng^.nodes)) input nothing nothing
  where
    f _      _ (Nothing, _)    (Just _, _) = error "not reached"
    f []     _ (Just n1, _)    (Just n2, _) = return (n1, n2)
    f []     i m1@(Just _, _)  (Nothing, _) =
        newNode i >>= \n -> f [] i m1 (Just n, infinity)
    f []     i m1@(Nothing, _) _ =
        newNode i >>= \n -> f [] i (Just n, infinity) m1
    f (n:ns) i m1@(_, mx1)     m2@(_, mx2) = if d < mx1
        then f ns i (Just n, d) m1
        else if d < mx2
            then f ns i m1 (Just n, d)
            else f ns i m1 m2
      where
        d = dist i (n^.value)

    nothing = (Nothing, infinity)
    infinity = 1 / 0 :: Double