module Data.Geo.Coordinate.Coordinate(
Coordinate
, AsCoordinate(..)
, (.#.)
, (<°>)
) where
import Control.Applicative(Applicative)
import Control.Category(Category(id, (.)))
import Control.Lens(Choice, swapped, Profunctor, Optic', (^.), iso, lens, prism', swapped, (^?), (#))
import Control.Monad(Monad(return))
import Data.Eq(Eq)
import Data.Geo.Coordinate.Latitude(AsLatitude(_Latitude), Latitude)
import Data.Geo.Coordinate.Longitude(AsLongitude(_Longitude), Longitude)
import Data.Geo.Coordinate.DegreesLatitude(AsDegreesLatitude(_DegreesLatitude), DegreesLatitude)
import Data.Geo.Coordinate.DegreesLongitude(AsDegreesLongitude(_DegreesLongitude), DegreesLongitude)
import Data.Geo.Coordinate.Minutes(Minutes)
import Data.Geo.Coordinate.Seconds(Seconds)
import Data.Maybe(Maybe)
import Data.Ord(Ord)
import Data.Tuple(curry, uncurry)
import Prelude(Double, Functor, Show, Double)
data Coordinate =
Coordinate
Latitude
Longitude
deriving (Eq, Ord, Show)
(.#.) ::
Latitude
-> Longitude
-> Coordinate
(.#.) =
Coordinate
(<°>) ::
Double
-> Double
-> Maybe Coordinate
(<°>) =
curry (^? _Coordinate)
class AsCoordinate p f s where
_Coordinate ::
Optic' p f s Coordinate
instance AsCoordinate p f Coordinate where
_Coordinate =
id
instance (Profunctor p, Functor f) => AsCoordinate p f (Latitude, Longitude) where
_Coordinate =
iso (uncurry Coordinate) (\(Coordinate lat lon) -> (lat, lon))
instance (Profunctor p, Functor f) => AsCoordinate p f (Longitude, Latitude) where
_Coordinate =
swapped . _Coordinate
instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLatitude, Minutes, Seconds), Longitude) where
_Coordinate =
iso
(\(lat, lon) -> Coordinate (lat ^. _Latitude) lon)
(\(Coordinate lat lon) -> (_Latitude # lat, lon))
instance (Profunctor p, Functor f) => AsCoordinate p f (Longitude, (DegreesLatitude, Minutes, Seconds)) where
_Coordinate =
swapped . _Coordinate
instance (Profunctor p, Functor f) => AsCoordinate p f (Latitude, (DegreesLongitude, Minutes, Seconds)) where
_Coordinate =
iso
(\(lat, lon) -> Coordinate lat (lon ^. _Longitude))
(\(Coordinate lat lon) -> (lat, _Longitude # lon))
instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLongitude, Minutes, Seconds), Latitude) where
_Coordinate =
swapped . _Coordinate
instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLatitude, Minutes, Seconds), (DegreesLongitude, Minutes, Seconds)) where
_Coordinate =
iso
(\(lat, lon) -> Coordinate (lat ^. _Latitude) (lon ^. _Longitude))
(\(Coordinate lat lon) -> (_Latitude # lat, _Longitude # lon))
instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLongitude, Minutes, Seconds), (DegreesLatitude, Minutes, Seconds)) where
_Coordinate =
swapped . _Coordinate
instance (Choice p, Applicative f) => AsCoordinate p f (Double, Double) where
_Coordinate =
prism'
(\(Coordinate lat lon) -> (_Latitude # lat, _Longitude # lon))
(\(lat, lon) ->
do lat' <- lat ^? _Latitude
lon' <- lon ^? _Longitude
return (Coordinate lat' lon'))
instance (Choice p, Applicative f) => AsCoordinate p f (Latitude, Double) where
_Coordinate =
prism'
(\(Coordinate lat lon) -> (lat, _Longitude # lon))
(\(lat, lon) ->
do lon' <- lon ^? _Longitude
return (Coordinate lat lon'))
instance (Choice p, Applicative f) => AsCoordinate p f (Double, Longitude) where
_Coordinate =
prism'
(\(Coordinate lat lon) -> (_Latitude # lat, lon))
(\(lat, lon) ->
do lat' <- lat ^? _Latitude
return (Coordinate lat' lon))
instance (Choice p, Applicative f) => AsCoordinate p f ((DegreesLatitude, Minutes, Seconds), Double) where
_Coordinate =
prism'
(\(Coordinate lat lon) -> (_Latitude # lat, _Longitude # lon))
(\(lat, lon) ->
do lat' <- lat ^? _Latitude
lon' <- lon ^? _Longitude
return (Coordinate lat' lon'))
instance (Choice p, Applicative f) => AsCoordinate p f (Double, (DegreesLongitude, Minutes, Seconds)) where
_Coordinate =
prism'
(\(Coordinate lat lon) -> (_Latitude # lat, _Longitude # lon))
(\(lat, lon) ->
do lat' <- lat ^? _Latitude
lon' <- lon ^? _Longitude
return (Coordinate lat' lon'))
instance (p ~ (->), Functor f) => AsLatitude p f Coordinate where
_Latitude =
lens (\(Coordinate lat _) -> lat) (\(Coordinate _ lon) lat -> Coordinate lat lon)
instance (p ~ (->), Functor f) => AsDegreesLatitude p f Coordinate where
_DegreesLatitude =
_Latitude . _DegreesLatitude
instance (p ~ (->), Functor f) => AsLongitude p f Coordinate where
_Longitude =
lens (\(Coordinate _ lon) -> lon) (\(Coordinate lat _) lon -> Coordinate lat lon)
instance (p ~ (->), Functor f) => AsDegreesLongitude p f Coordinate where
_DegreesLongitude =
_Longitude . _DegreesLongitude