module System.Monopati (Path (..), Points (..), Reference (..)
, part, points, next, (<^>), (</>)) where
import "base" Data.Function ((.), ($))
import "base" Data.Maybe (Maybe (Just, Nothing))
import "base" Data.String (String)
import "base" Data.Semigroup ((<>))
import "base" Text.Show (Show (show))
import "comonad" Control.Comonad (extract)
import "free" Control.Comonad.Cofree (Cofree ((:<)))
type Stack = Cofree Maybe
data Reference = Absolute | Relative
data Points = Directory | File
data Path (reference :: Reference) (points :: Points) = Path { path :: Stack String }
instance Show (Path Absolute points) where
show (Path (x :< Just xs)) = show (Path @Absolute xs) <> "/" <> x
show (Path (x :< Nothing)) = "/" <> x
instance Show (Path Relative points) where
show (Path (x :< Just xs)) = x <> "/" <> show (Path @Relative xs)
show (Path (x :< Nothing)) = x
part :: String -> Path referece points
part x = Path $ x :< Nothing
points :: Path Absolute points -> String
points = extract . path
next :: Path Relative points -> String
next = extract . path
(<^>) :: Path Relative Directory -> Path Relative points -> Path Relative points
Path (x :< Nothing) <^> Path that = Path $ x :< Just that
Path (x :< Just this) <^> Path that = part x <^> (Path this <^> Path that)
(</>) :: Path Absolute Directory -> Path Relative points -> Path Absolute points
Path absolute </> Path (x :< Nothing) = Path . (:<) x . Just $ absolute
Path absolute </> Path (x :< Just xs) = (Path . (:<) x . Just $ absolute) </> Path xs