module Control.Instances.ShortestPath where
import Control.Monad.Identity
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.List
import Control.Monad.State
import Data.Maybe
import Data.Proxy
import GHC.TypeLits
import Control.Instances.TypeLevelPrelude
data Connect m1 m2
data Connect_2m m1 m2
data Connect_mt mt
data Connect_id m
data Connect_MU m
data NoPathFound
type family ShortestPath (e :: [*]) (s :: * -> *) (t :: * -> *) :: [*] where
ShortestPath e t t = '[]
ShortestPath e Identity t = '[ Connect_id t ]
ShortestPath e s Proxy = '[ Connect_MU s ]
ShortestPath e s t = ShortestPath' e s (InitCurrent e t)
type family ShortestPath' (e :: [*]) (s :: * -> *) (c :: [[*]]) :: [*] where
ShortestPath' e s '[] = '[ NoPathFound ]
ShortestPath' e s c = FromMaybe (ShortestPath' e s (ApplyEdges e c c))
(GetFinished s c)
type family GetFinished s c where
GetFinished s ((Connect s b ': p) ': lls)
= Just (Connect s b ': p)
GetFinished s (p ': lls) = GetFinished s lls
GetFinished s '[] = Nothing
type family InitCurrent (e :: [*]) (t :: * -> *) :: [[*]] where
InitCurrent '[] t = '[]
InitCurrent (e ': es) t = IfJust (ApplyEdge e t)
('[ MonomorphEnd e t ] ': InitCurrent es t)
(InitCurrent es t)
type family ApplyEdges (e :: [*]) (co :: [[*]]) (c :: [[*]]) :: [[*]] where
ApplyEdges (e ': es) co ((Connect s b ': p) ': cs)
= AppendJust (IfThenJust (IsJust (ApplyEdge e s))
(MonomorphEnd e s ': Connect s b ': p))
(ApplyEdges (e ': es) co cs)
ApplyEdges (e ': es) co '[] = ApplyEdges es co co
ApplyEdges '[] co cr = '[]
type family ApplyEdge e t :: Maybe (* -> *) where
ApplyEdge (Connect ms mr) mr = Just ms
ApplyEdge (Connect_2m ms mt) (mt m) = Just ms
ApplyEdge (Connect_mt mt) (mt m) = Just m
ApplyEdge e t = Nothing
type family MonomorphEnd c v :: * where
MonomorphEnd (Connect_2m m m') v = Connect m v
MonomorphEnd (Connect_mt t) (t m) = Connect m (t m)
MonomorphEnd c v = c