packages feed

coordinate 0.0.10 → 0.0.11

raw patch · 11 files changed

+451/−431 lines, 11 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.Geo.Coordinate.Coordinate: (<㎭>) :: Double -> Double -> Maybe Coordinate
- Data.Geo.Coordinate.Coordinate: class HasCoordinate t
- Data.Geo.Coordinate.Coordinate: coordinate :: HasCoordinate t => Lens' t Coordinate
- Data.Geo.Coordinate.Coordinate: coordinateDMSLatDMSLon :: Iso' ((DegreesLatitude, Minutes, Seconds), (DegreesLongitude, Minutes, Seconds)) Coordinate
- Data.Geo.Coordinate.Coordinate: coordinateDMSLatLon :: Iso' ((DegreesLatitude, Minutes, Seconds), Longitude) Coordinate
- Data.Geo.Coordinate.Coordinate: coordinateLatDMSLon :: Iso' (Latitude, (DegreesLongitude, Minutes, Seconds)) Coordinate
- Data.Geo.Coordinate.Coordinate: coordinateLatLon :: Iso' (Latitude, Longitude) Coordinate
- Data.Geo.Coordinate.Coordinate: coordinateLonLat :: Iso' (Longitude, Latitude) Coordinate
- Data.Geo.Coordinate.Coordinate: fracCoordinate :: Prism' (Double, Double) Coordinate
- Data.Geo.Coordinate.Coordinate: instance HasCoordinate Coordinate
- Data.Geo.Coordinate.Coordinate: instance HasDegreesLatitude Coordinate
- Data.Geo.Coordinate.Coordinate: instance HasDegreesLongitude Coordinate
- Data.Geo.Coordinate.Coordinate: instance HasLatitude Coordinate
- Data.Geo.Coordinate.Coordinate: instance HasLongitude Coordinate
- Data.Geo.Coordinate.Coordinate: radianCoordinate :: Prism' (Double, Double) Coordinate
- Data.Geo.Coordinate.DegreesLatitude: class HasDegreesLatitude t
- Data.Geo.Coordinate.DegreesLatitude: degreesLatitude :: HasDegreesLatitude t => Lens' t DegreesLatitude
- Data.Geo.Coordinate.DegreesLatitude: instance HasDegreesLatitude DegreesLatitude
- Data.Geo.Coordinate.DegreesLatitude: nDegreesLatitude :: Prism' Int DegreesLatitude
- Data.Geo.Coordinate.DegreesLongitude: class HasDegreesLongitude t
- Data.Geo.Coordinate.DegreesLongitude: degreesLongitude :: HasDegreesLongitude t => Lens' t DegreesLongitude
- Data.Geo.Coordinate.DegreesLongitude: instance HasDegreesLongitude DegreesLongitude
- Data.Geo.Coordinate.DegreesLongitude: nDegreesLongitude :: Prism' Int DegreesLongitude
- Data.Geo.Coordinate.Latitude: class HasLatitude t
- Data.Geo.Coordinate.Latitude: dmsLatitude :: Iso' (DegreesLatitude, Minutes, Seconds) Latitude
- Data.Geo.Coordinate.Latitude: fracLatitude :: Prism' Double Latitude
- Data.Geo.Coordinate.Latitude: instance HasDegreesLatitude Latitude
- Data.Geo.Coordinate.Latitude: instance HasLatitude Latitude
- Data.Geo.Coordinate.Latitude: instance HasMinutes Latitude
- Data.Geo.Coordinate.Latitude: instance HasSeconds Latitude
- Data.Geo.Coordinate.Latitude: latitude :: HasLatitude t => Lens' t Latitude
- Data.Geo.Coordinate.Latitude: radianLatitude :: Prism' Double Latitude
- Data.Geo.Coordinate.Longitude: class HasLongitude t
- Data.Geo.Coordinate.Longitude: dmsLongitude :: Iso' (DegreesLongitude, Minutes, Seconds) Longitude
- Data.Geo.Coordinate.Longitude: instance HasDegreesLongitude Longitude
- Data.Geo.Coordinate.Longitude: instance HasLongitude Longitude
- Data.Geo.Coordinate.Longitude: instance HasMinutes Longitude
- Data.Geo.Coordinate.Longitude: instance HasSeconds Longitude
- Data.Geo.Coordinate.Longitude: longitude :: HasLongitude t => Lens' t Longitude
- Data.Geo.Coordinate.Longitude: radianLongitude :: Prism' Double Longitude
- Data.Geo.Coordinate.Minutes: class HasMinutes t
- Data.Geo.Coordinate.Minutes: instance HasMinutes Minutes
- Data.Geo.Coordinate.Minutes: minutes :: HasMinutes t => Lens' t Minutes
- Data.Geo.Coordinate.Minutes: nMinutes :: Prism' Int Minutes
- Data.Geo.Coordinate.Seconds: class HasSeconds t
- Data.Geo.Coordinate.Seconds: instance HasSeconds Seconds
- Data.Geo.Coordinate.Seconds: nSeconds :: Prism' Double Seconds
- Data.Geo.Coordinate.Seconds: seconds :: HasSeconds t => Lens' t Seconds
+ Data.Geo.Coordinate.Coordinate: _Coordinate :: AsCoordinate p f s => Optic' p f s Coordinate
+ Data.Geo.Coordinate.Coordinate: class AsCoordinate p f s
+ Data.Geo.Coordinate.Coordinate: instance (Choice p, Applicative f) => AsCoordinate p f ((DegreesLatitude, Minutes, Seconds), Double)
+ Data.Geo.Coordinate.Coordinate: instance (Choice p, Applicative f) => AsCoordinate p f (Double, (DegreesLongitude, Minutes, Seconds))
+ Data.Geo.Coordinate.Coordinate: instance (Choice p, Applicative f) => AsCoordinate p f (Double, Double)
+ Data.Geo.Coordinate.Coordinate: instance (Choice p, Applicative f) => AsCoordinate p f (Double, Longitude)
+ Data.Geo.Coordinate.Coordinate: instance (Choice p, Applicative f) => AsCoordinate p f (Latitude, Double)
+ Data.Geo.Coordinate.Coordinate: instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLatitude, Minutes, Seconds), (DegreesLongitude, Minutes, Seconds))
+ Data.Geo.Coordinate.Coordinate: instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLatitude, Minutes, Seconds), Longitude)
+ Data.Geo.Coordinate.Coordinate: instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLongitude, Minutes, Seconds), (DegreesLatitude, Minutes, Seconds))
+ Data.Geo.Coordinate.Coordinate: instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLongitude, Minutes, Seconds), Latitude)
+ Data.Geo.Coordinate.Coordinate: instance (Profunctor p, Functor f) => AsCoordinate p f (Latitude, (DegreesLongitude, Minutes, Seconds))
+ Data.Geo.Coordinate.Coordinate: instance (Profunctor p, Functor f) => AsCoordinate p f (Latitude, Longitude)
+ Data.Geo.Coordinate.Coordinate: instance (Profunctor p, Functor f) => AsCoordinate p f (Longitude, (DegreesLatitude, Minutes, Seconds))
+ Data.Geo.Coordinate.Coordinate: instance (Profunctor p, Functor f) => AsCoordinate p f (Longitude, Latitude)
+ Data.Geo.Coordinate.Coordinate: instance (p ~ (->), Functor f) => AsDegreesLatitude p f Coordinate
+ Data.Geo.Coordinate.Coordinate: instance (p ~ (->), Functor f) => AsDegreesLongitude p f Coordinate
+ Data.Geo.Coordinate.Coordinate: instance (p ~ (->), Functor f) => AsLatitude p f Coordinate
+ Data.Geo.Coordinate.Coordinate: instance (p ~ (->), Functor f) => AsLongitude p f Coordinate
+ Data.Geo.Coordinate.Coordinate: instance AsCoordinate p f Coordinate
+ Data.Geo.Coordinate.DegreesLatitude: _DegreesLatitude :: AsDegreesLatitude p f s => Optic' p f s DegreesLatitude
+ Data.Geo.Coordinate.DegreesLatitude: class AsDegreesLatitude p f s
+ Data.Geo.Coordinate.DegreesLatitude: instance (Choice p, Applicative f) => AsDegreesLatitude p f Int
+ Data.Geo.Coordinate.DegreesLatitude: instance AsDegreesLatitude p f DegreesLatitude
+ Data.Geo.Coordinate.DegreesLongitude: _DegreesLongitude :: AsDegreesLongitude p f s => Optic' p f s DegreesLongitude
+ Data.Geo.Coordinate.DegreesLongitude: class AsDegreesLongitude p f s
+ Data.Geo.Coordinate.DegreesLongitude: instance (Choice p, Applicative f) => AsDegreesLongitude p f Int
+ Data.Geo.Coordinate.DegreesLongitude: instance AsDegreesLongitude p f DegreesLongitude
+ Data.Geo.Coordinate.Latitude: _Latitude :: AsLatitude p f s => Optic' p f s Latitude
+ Data.Geo.Coordinate.Latitude: class AsLatitude p f s
+ Data.Geo.Coordinate.Latitude: instance (Choice p, Applicative f) => AsLatitude p f Double
+ Data.Geo.Coordinate.Latitude: instance (Profunctor p, Functor f) => AsLatitude p f (DegreesLatitude, Minutes, Seconds)
+ Data.Geo.Coordinate.Latitude: instance (p ~ (->), Functor f) => AsDegreesLatitude p f Latitude
+ Data.Geo.Coordinate.Latitude: instance (p ~ (->), Functor f) => AsMinutes p f Latitude
+ Data.Geo.Coordinate.Latitude: instance (p ~ (->), Functor f) => AsSeconds p f Latitude
+ Data.Geo.Coordinate.Latitude: instance AsLatitude p f Latitude
+ Data.Geo.Coordinate.Longitude: _Longitude :: AsLongitude p f s => Optic' p f s Longitude
+ Data.Geo.Coordinate.Longitude: class AsFracLongitude t
+ Data.Geo.Coordinate.Longitude: class AsLongitude p f s
+ Data.Geo.Coordinate.Longitude: instance (Choice p, Applicative f) => AsLongitude p f Double
+ Data.Geo.Coordinate.Longitude: instance (Profunctor p, Functor f) => AsLongitude p f (DegreesLongitude, Minutes, Seconds)
+ Data.Geo.Coordinate.Longitude: instance (p ~ (->), Functor f) => AsDegreesLongitude p f Longitude
+ Data.Geo.Coordinate.Longitude: instance (p ~ (->), Functor f) => AsMinutes p f Longitude
+ Data.Geo.Coordinate.Longitude: instance (p ~ (->), Functor f) => AsSeconds p f Longitude
+ Data.Geo.Coordinate.Longitude: instance AsFracLongitude Longitude
+ Data.Geo.Coordinate.Longitude: instance AsLongitude p f Longitude
+ Data.Geo.Coordinate.Minutes: _Minutes :: AsMinutes p f s => Optic' p f s Minutes
+ Data.Geo.Coordinate.Minutes: class AsMinutes p f s
+ Data.Geo.Coordinate.Minutes: instance (Choice p, Applicative f) => AsMinutes p f Int
+ Data.Geo.Coordinate.Minutes: instance AsMinutes p f Minutes
+ Data.Geo.Coordinate.Seconds: _Seconds :: AsSeconds p f s => Optic' p f s Seconds
+ Data.Geo.Coordinate.Seconds: class AsSeconds p f s
+ Data.Geo.Coordinate.Seconds: instance (Choice p, Applicative f) => AsSeconds p f Double
+ Data.Geo.Coordinate.Seconds: instance AsSeconds p f Seconds
- Data.Geo.Coordinate.Longitude: fracLongitude :: Prism' Double Longitude
+ Data.Geo.Coordinate.Longitude: fracLongitude :: AsFracLongitude t => Prism' Double t

Files

+ LICENCE view
@@ -0,0 +1,27 @@+Copyright 2013-2014 Tony Morris++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ changelog view
@@ -0,0 +1,10 @@+0.0.11++* Use Optic to overload lenses, prisms and isos.++* Remove use of radians (for now).++0.0.10++This change log started.+
coordinate.cabal view
@@ -1,7 +1,7 @@ name:               coordinate-version:            0.0.10+version:            0.0.11 license:            BSD3-license-file:       etc/LICENCE+license-file:       LICENCE author:             Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ> maintainer:         Tony Morris copyright:          Copyright (C) 2013-2014 Tony Morris@@ -12,6 +12,7 @@ bug-reports:        https://github.com/tonymorris/coordinate/issues cabal-version:      >= 1.10 build-type:         Custom+extra-source-files: changelog  source-repository   head   type:             git
− etc/LICENCE
@@ -1,27 +0,0 @@-Copyright 2013-2014 Tony Morris--All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions-are met:-1. Redistributions of source code must retain the above copyright-   notice, this list of conditions and the following disclaimer.-2. Redistributions in binary form must reproduce the above copyright-   notice, this list of conditions and the following disclaimer in the-   documentation and/or other materials provided with the distribution.-3. Neither the name of the author nor the names of his contributors-   may be used to endorse or promote products derived from this software-   without specific prior written permission.--THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF-SUCH DAMAGE.
src/Data/Geo/Coordinate/Coordinate.hs view
@@ -1,35 +1,31 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}  module Data.Geo.Coordinate.Coordinate(   Coordinate+, AsCoordinate(..) , (.#.) , (<°>)-, (<㎭>)-, fracCoordinate-, radianCoordinate-, HasCoordinate(..)-, coordinateLatLon-, coordinateLonLat-, coordinateDMSLatLon-, coordinateLatDMSLon-, coordinateDMSLatDMSLon ) where +import Control.Applicative(Applicative) import Control.Category(Category(id, (.)))-import Control.Lens(Iso', Lens', Prism', iso, lens, prism', mapping, swapped, withIso, (^?), (#))+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(HasLatitude(latitude), Latitude, dmsLatitude, radianLatitude, fracLatitude)-import Data.Geo.Coordinate.Longitude(HasLongitude(longitude), Longitude, dmsLongitude, radianLongitude, fracLongitude)-import Data.Geo.Coordinate.DegreesLatitude(HasDegreesLatitude(degreesLatitude), DegreesLatitude)-import Data.Geo.Coordinate.DegreesLongitude(HasDegreesLongitude(degreesLongitude), DegreesLongitude)+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(Show, Double)+import Prelude(Double, Functor, Show, Double)  data Coordinate =   Coordinate@@ -52,96 +48,109 @@   -> Double   -> Maybe Coordinate (<°>) =-  curry (^? fracCoordinate)+  curry (^? _Coordinate) --- | Build a coordinate from a radian latitude and fractional longitude. Fails--- if either are out of range.-(<㎭>) ::-  Double-  -> Double-  -> Maybe Coordinate-(<㎭>) =-  curry (^? radianCoordinate)- -coordinatePrism ::-  Prism' Double Latitude-  -> Prism' Double Longitude-  -> Prism' (Double, Double) Coordinate-coordinatePrism f g =-  prism'-    (\x -> let (b, d) = coordinateLatLon # x-           in (f # b, g # d))-    (\(lat, lon) ->-      do lat' <- lat ^? f-         lon' <- lon ^? g-         return (Coordinate lat' lon'))+class AsCoordinate p f s where+  _Coordinate ::+    Optic' p f s Coordinate --- | A prism on the pair (below) to a coordinate:--- --- * a fractional latitude to a double between -90 and 90 exclusive.------ * a fractional longitude to a double between -180 and 180 exclusive.-fracCoordinate ::-  Prism' (Double, Double) Coordinate-fracCoordinate =-  coordinatePrism fracLatitude fracLongitude+instance AsCoordinate p f Coordinate where+  _Coordinate =+    id --- | A prism on the pair (below) to a coordinate:--- --- * a radian latitude to a double between -π/2 and π/2 exclusive.------ * a radian longitude to a double between -π and π exclusive.-radianCoordinate ::-  Prism' (Double, Double) Coordinate-radianCoordinate =-  coordinatePrism radianLatitude radianLongitude-  -coordinateLatLon ::-  Iso' (Latitude, Longitude) Coordinate-coordinateLatLon =-  iso (uncurry Coordinate) (\(Coordinate lat lon) -> (lat, lon))+instance (Profunctor p, Functor f) => AsCoordinate p f (Latitude, Longitude) where+  _Coordinate =+    iso (uncurry Coordinate) (\(Coordinate lat lon) -> (lat, lon)) -coordinateLonLat ::-  Iso' (Longitude, Latitude) Coordinate-coordinateLonLat =-  swapped . coordinateLatLon+instance (Profunctor p, Functor f) => AsCoordinate p f (Longitude, Latitude) where+  _Coordinate =+    swapped . _Coordinate -coordinateDMSLatLon ::-  Iso' ((DegreesLatitude, Minutes, Seconds), Longitude) Coordinate-coordinateDMSLatLon =-  swapped . mapping dmsLatitude . coordinateLonLat+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)) -coordinateLatDMSLon ::-  Iso' (Latitude, (DegreesLongitude, Minutes, Seconds)) Coordinate-coordinateLatDMSLon =-  mapping dmsLongitude . coordinateLatLon+instance (Profunctor p, Functor f) => AsCoordinate p f (Longitude, (DegreesLatitude, Minutes, Seconds)) where+  _Coordinate =+    swapped . _Coordinate -coordinateDMSLatDMSLon ::-  Iso' ((DegreesLatitude, Minutes, Seconds), (DegreesLongitude, Minutes, Seconds)) Coordinate-coordinateDMSLatDMSLon =-  iso (\((td, tm, ts), (nd, nm, ns)) -> Coordinate (withIso dmsLatitude (\k _ -> k (td, tm, ts))) (withIso dmsLongitude (\k _ -> k (nd, nm, ns))))-      (\(Coordinate lat lon) -> (withIso dmsLatitude (\_ k -> k lat), withIso dmsLongitude (\_ k -> k lon)))+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)) -class HasCoordinate t where-  coordinate ::-    Lens' t Coordinate+instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLongitude, Minutes, Seconds), Latitude) where+  _Coordinate =+    swapped . _Coordinate -instance HasCoordinate Coordinate where-  coordinate =-    id+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 HasLatitude Coordinate where-  latitude =-    lens (\(Coordinate lat _) -> lat) (\(Coordinate _ lon) lat -> Coordinate lat lon)+instance (Profunctor p, Functor f) => AsCoordinate p f ((DegreesLongitude, Minutes, Seconds), (DegreesLatitude, Minutes, Seconds)) where+  _Coordinate =+    swapped . _Coordinate -instance HasLongitude Coordinate where-  longitude =-    lens (\(Coordinate _ lon) -> lon) (\(Coordinate lat _) lon -> Coordinate lat lon)+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 HasDegreesLatitude Coordinate where-  degreesLatitude =-    latitude . degreesLatitude+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 HasDegreesLongitude Coordinate where-  degreesLongitude =-    longitude . degreesLongitude+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
src/Data/Geo/Coordinate/DegreesLatitude.hs view
@@ -1,13 +1,15 @@ {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}  module Data.Geo.Coordinate.DegreesLatitude(   DegreesLatitude-, HasDegreesLatitude(..)-, nDegreesLatitude+, AsDegreesLatitude(..) ) where +import Control.Applicative(Applicative) import Control.Category(Category(id))-import Control.Lens(Prism', Lens', prism')+import Control.Lens(Optic', Choice, prism') import Data.Bool((&&)) import Data.Eq(Eq) import Data.Int(Int)@@ -24,41 +26,39 @@   DegreesLatitude Int   deriving (Eq, Ord, Show) +class AsDegreesLatitude p f s where+  _DegreesLatitude ::+    Optic' p f s DegreesLatitude++instance AsDegreesLatitude p f DegreesLatitude where+  _DegreesLatitude =+    id+ -- | A prism on degrees latitude to an integer between -90 and 90 exclusive. ----- >>> 7 ^? nDegreesLatitude+-- >>> (7 :: Int) ^? _DegreesLatitude -- Just (DegreesLatitude 7) ----- >>> 0 ^? nDegreesLatitude+-- >>> (0 :: Int) ^? _DegreesLatitude -- Just (DegreesLatitude 0) ----- >>> 89 ^? nDegreesLatitude+-- >>> (89 :: Int) ^? _DegreesLatitude -- Just (DegreesLatitude 89) ----- >>> 90 ^? nDegreesLatitude+-- >>> (90 :: Int) ^? _DegreesLatitude -- Nothing ----- >>> (-89) ^? nDegreesLatitude+-- >>> (-89 :: Int) ^? _DegreesLatitude -- Just (DegreesLatitude (-89)) ----- >>> (-90) ^? nDegreesLatitude+-- >>> (-90 :: Int) ^? _DegreesLatitude -- Nothing ----- prop> all (\m -> nDegreesLatitude # m == n) (n ^? nDegreesLatitude)-nDegreesLatitude ::-  Prism' Int DegreesLatitude-nDegreesLatitude =-  prism'-    (\(DegreesLatitude i) -> i)-    (\i -> if i > -90 && i < 90-             then Just (DegreesLatitude i)-             else Nothing)--class HasDegreesLatitude t where-  degreesLatitude ::-    Lens' t DegreesLatitude--instance HasDegreesLatitude DegreesLatitude where-  degreesLatitude =-    id-+-- prop> all (\m -> _DegreesLatitude # m == (n :: Int)) (n ^? _DegreesLatitude)+instance (Choice p, Applicative f) => AsDegreesLatitude p f Int where+  _DegreesLatitude =+    prism'+      (\(DegreesLatitude i) -> i)+      (\i -> if i > -90 && i < 90+               then Just (DegreesLatitude i)+               else Nothing)
src/Data/Geo/Coordinate/DegreesLongitude.hs view
@@ -1,13 +1,15 @@ {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}  module Data.Geo.Coordinate.DegreesLongitude(   DegreesLongitude-, HasDegreesLongitude(..)-, nDegreesLongitude+, AsDegreesLongitude(..) ) where +import Control.Applicative(Applicative) import Control.Category(Category(id))-import Control.Lens(Prism', Lens', prism')+import Control.Lens(Optic', Choice, prism') import Data.Bool((&&)) import Data.Eq(Eq) import Data.Int(Int)@@ -24,40 +26,39 @@   DegreesLongitude Int   deriving (Eq, Ord, Show) +class AsDegreesLongitude p f s where+  _DegreesLongitude ::+    Optic' p f s DegreesLongitude++instance AsDegreesLongitude p f DegreesLongitude where+  _DegreesLongitude =+    id+ -- | A prism on degrees longitude to an integer between -180 and 180 exclusive. ----- >>> 7 ^? nDegreesLongitude+-- >>> (7 :: Int) ^? _DegreesLongitude -- Just (DegreesLongitude 7) ----- >>> 0 ^? nDegreesLongitude+-- >>> (0 :: Int) ^? _DegreesLongitude -- Just (DegreesLongitude 0) ----- >>> 179 ^? nDegreesLongitude+-- >>> (179 :: Int) ^? _DegreesLongitude -- Just (DegreesLongitude 179) ----- >>> 180 ^? nDegreesLongitude+-- >>> (180 :: Int) ^? _DegreesLongitude -- Nothing ----- >>> (-179) ^? nDegreesLongitude+-- >>> (-179 :: Int) ^? _DegreesLongitude -- Just (DegreesLongitude (-179)) ----- >>> (-180) ^? nDegreesLongitude+-- >>> (-180 :: Int) ^? _DegreesLongitude -- Nothing ----- prop> all (\m -> nDegreesLongitude # m == n) (n ^? nDegreesLongitude)-nDegreesLongitude ::-  Prism' Int DegreesLongitude-nDegreesLongitude  =-  prism'-    (\(DegreesLongitude i) -> i)-    (\i -> if i > -180 && i < 180-             then Just (DegreesLongitude i)-             else Nothing)--class HasDegreesLongitude t where-  degreesLongitude ::-    Lens' t DegreesLongitude--instance HasDegreesLongitude DegreesLongitude where-  degreesLongitude =-    id+-- prop> all (\m -> _DegreesLongitude # m == (n :: Int)) (n ^? _DegreesLongitude)+instance (Choice p, Applicative f) => AsDegreesLongitude p f Int where+  _DegreesLongitude =+    prism'+      (\(DegreesLongitude i) -> i)+      (\i -> if i > -180 && i < 180+               then Just (DegreesLongitude i)+               else Nothing)
src/Data/Geo/Coordinate/Latitude.hs view
@@ -1,25 +1,27 @@ {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}  module Data.Geo.Coordinate.Latitude(   Latitude-, HasLatitude(..)-, dmsLatitude-, fracLatitude-, radianLatitude+, AsLatitude(..) ) where -import Control.Category(Category(id, (.)))-import Control.Lens(Iso', Prism', Lens', iso, prism', lens, (#), (^?))+import Control.Applicative(Applicative)+import Control.Category(Category(id))+import Control.Lens(Choice, Profunctor, Optic', iso, prism', lens, (#), (^?)) import Control.Monad(Monad(return)) import Data.Eq(Eq)-import Data.Geo.Coordinate.DegreesLatitude(HasDegreesLatitude(degreesLatitude), DegreesLatitude, nDegreesLatitude)-import Data.Geo.Coordinate.Minutes(HasMinutes(minutes), Minutes, nMinutes)-import Data.Geo.Coordinate.Seconds(HasSeconds(seconds), Seconds, nSeconds)+import Data.Geo.Coordinate.DegreesLatitude(DegreesLatitude, AsDegreesLatitude(_DegreesLatitude))+import Data.Geo.Coordinate.Minutes(AsMinutes(_Minutes), Minutes)+import Data.Geo.Coordinate.Seconds(AsSeconds(_Seconds), Seconds) import Data.Ord(Ord((<)))-import Prelude(Double, Show, Num((+), (*), (-), abs), Floating(pi), Fractional((/)), properFraction, fromIntegral)+import Prelude(Functor, Double, Show, Int, Num((+), (*), (-), abs), Fractional((/)), properFraction, fromIntegral)  -- $setup -- >>> import Prelude(Functor(..))+-- >>> import Data.Maybe  data Latitude =   Latitude@@ -28,139 +30,107 @@     Seconds   deriving (Eq, Ord, Show) +class AsLatitude p f s where+  _Latitude ::+    Optic' p f s Latitude++instance AsLatitude p f Latitude where+  _Latitude =+    id+ -- | An isomorphism on the triple of degrees latitude, minutes, seconds to a latitude. ----- >>> do deg <- 7 ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- >>> do deg <- (7 :: Int) ^? _DegreesLatitude; min <- (7 :: Int) ^? _Minutes; sec <- (7 :: Double) ^? _Seconds; (deg, min, sec) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude 7) (Minutes 7) (Seconds 7.0000)) ----- >>> do deg <- 89 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- >>> do deg <- (89 :: Int) ^? _DegreesLatitude; min <- (59 :: Int) ^? _Minutes; sec <- (59 :: Double) ^? _Seconds; (deg, min, sec) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude 89) (Minutes 59) (Seconds 59.0000)) ----- >>> do deg <- (-7) ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- >>> do deg <- (-7 :: Int) ^? _DegreesLatitude; min <- (7 :: Int) ^? _Minutes; sec <- (7 :: Double) ^? _Seconds; (deg, min, sec) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude (-7)) (Minutes 7) (Seconds 7.0000)) ----- >>> do deg <- (-89) ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- >>> do deg <- (-89 :: Int) ^? _DegreesLatitude; min <- (59 :: Int) ^? _Minutes; sec <- (59 :: Double) ^? _Seconds; (deg, min, sec) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude (-89)) (Minutes 59) (Seconds 59.0000)) ----- >>> do deg <- 90 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- >>> do deg <- (90 :: Int) ^? _DegreesLatitude; min <- (59 :: Int) ^? _Minutes; sec <- (59 :: Double) ^? _Seconds; (deg, min, sec) ^? _Latitude :: Maybe Latitude -- Nothing ----- >>> do deg <- 89 ^? nDegreesLatitude; min <- 60 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- >>> do deg <- (89 :: Int) ^? _DegreesLatitude; min <- (60 :: Int) ^? _Minutes; sec <- (59 :: Double) ^? _Seconds; (deg, min, sec) ^? _Latitude :: Maybe Latitude -- Nothing ----- >>> do deg <- 89 ^? nDegreesLatitude; min <- 59 ^? nMinutes; sec <- 60 ^? nSeconds; (deg, min, sec) ^? dmsLatitude+-- >>> do deg <- (89 :: Int) ^? _DegreesLatitude; min <- (59 :: Int) ^? _Minutes; sec <- (60 :: Double) ^? _Seconds; (deg, min, sec) ^? _Latitude :: Maybe Latitude -- Nothing ----- >>> fmap (dmsLatitude #)  (7 ^? fracLatitude)+-- >>> fmap (\x -> _Latitude # x :: (DegreesLatitude, Minutes, Seconds))  ((7 :: Double) ^? _Latitude :: Maybe Latitude) -- Just (DegreesLatitude 7,Minutes 0,Seconds 0.0000) ----- >>> fmap (dmsLatitude #)  (7.12 ^? fracLatitude)+-- >>> fmap (\x -> _Latitude # x :: (DegreesLatitude, Minutes, Seconds))  ((7.12 :: Double) ^? _Latitude :: Maybe Latitude) -- Just (DegreesLatitude 7,Minutes 7,Seconds 12.0000)-dmsLatitude ::-  Iso' (DegreesLatitude, Minutes, Seconds) Latitude-dmsLatitude =-  iso (\(d, m, s) -> Latitude d m s) (\(Latitude d m s) -> (d, m, s))+instance (Profunctor p, Functor f) => AsLatitude p f (DegreesLatitude, Minutes, Seconds) where+  _Latitude =+    iso (\(d, m, s) -> Latitude d m s) (\(Latitude d m s) -> (d, m, s))  -- | A prism on latitude to a double between -90 and 90 exclusive. ----- >>> 7 ^? fracLatitude+-- >>> (7 :: Double) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude 7) (Minutes 0) (Seconds 0.0000)) ----- >>> (-7) ^? fracLatitude+-- >>> (-7 :: Double) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude (-7)) (Minutes 0) (Seconds 0.0000)) ----- >>> 7.12 ^? fracLatitude+-- >>> (7.12 :: Double) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude 7) (Minutes 7) (Seconds 12.0000)) ----- >>> (-7.12) ^? fracLatitude+-- >>> (-7.12 :: Double) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude (-7)) (Minutes 7) (Seconds 12.0000)) ----- >>> fmap (fracLatitude #) (7.12 ^? fracLatitude)+-- >>> fmap (\x -> _Latitude # x :: Double) ((7.12 :: Double) ^? _Latitude :: Maybe Latitude) -- Just 7.12 ----- >>> fmap (fracLatitude #) ((-7.12) ^? fracLatitude)+-- >>> fmap (\x -> _Latitude # x :: Double) ((-7.12 :: Double) ^? _Latitude :: Maybe Latitude) -- Just (-7.12) ----- >>> 90 ^? fracLatitude+-- >>> (90 :: Double) ^? _Latitude :: Maybe Latitude -- Nothing ----- >>> (-90) ^? fracLatitude+-- >>> (-90 :: Double) ^? _Latitude :: Maybe Latitude -- Nothing ----- >>> 15.63791 ^? fracLatitude+-- >>> (15.63791 :: Double) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude 15) (Minutes 38) (Seconds 16.4760)) ----- >>> 89.1 ^? fracLatitude+-- >>> (89.1 :: Double) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude 89) (Minutes 5) (Seconds 60.0000)) ----- >>> 89.2 ^? fracLatitude+-- >>> (89.2 :: Double) ^? _Latitude :: Maybe Latitude -- Just (Latitude (DegreesLatitude 89) (Minutes 12) (Seconds 0.0000)) ----- >>> fmap (fracLatitude #) (do deg <- 7 ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude)+-- >>> fmap (\x -> _Latitude # x :: Double) (do deg <- (7 :: Int) ^? _DegreesLatitude; min <- (7 :: Int) ^? _Minutes; sec <- (7 :: Double) ^? _Seconds; (deg, min, sec) ^? _Latitude :: Maybe Latitude) -- Just 7.118611111111111 ----- >>> fmap (fracLatitude #) (do deg <- 89 ^? nDegreesLatitude; min <- 15 ^? nMinutes; sec <- 6 ^? nSeconds; (deg, min, sec) ^? dmsLatitude)+-- >>> fmap (\x -> _Latitude # x  :: Double) (do deg <- (89 :: Int) ^? _DegreesLatitude; min <- (15 :: Int) ^? _Minutes; sec <- (6 :: Double) ^? _Seconds; (deg, min, sec) ^? _Latitude :: Maybe Latitude) -- Just 89.25166666666667-fracLatitude ::-  Prism' Double Latitude-fracLatitude =-  prism' (\(Latitude d m s) ->-    let p = fromIntegral (nDegreesLatitude # d)-        q = (fromIntegral (nMinutes # m) / 60) + (nSeconds # s) / 3600+instance (Choice p, Applicative f) => AsLatitude p f Double where+  _Latitude =+    prism' (\(Latitude d m s) ->+    let p = fromIntegral (_DegreesLatitude # d :: Int)+        q = (fromIntegral (_Minutes # m :: Int) / 60) + (_Seconds # s) / 3600     in (if p < 0 then (-) else (+)) p q)     (\x -> let (d, z) = properFraction x                (m, s) = properFraction ((z :: Double) * 60)-           in do d' <- d ^? nDegreesLatitude-                 m' <- abs m ^? nMinutes-                 s' <- (abs s * 60) ^? nSeconds+           in do d' <- (d :: Int) ^? _DegreesLatitude+                 m' <- (abs m :: Int) ^? _Minutes+                 s' <- (abs s * 60) ^? _Seconds                  return (Latitude d' m' s')) --- | A prism on latitude to a double between -π/2 and π/2 exclusive.------ >>> 0.2 ^? radianLatitude--- Just (Latitude (DegreesLatitude 11) (Minutes 27) (Seconds 32.9612))------ >>> 1.3 ^? radianLatitude--- Just (Latitude (DegreesLatitude 74) (Minutes 29) (Seconds 4.2481))------ >>> (-1.3) ^? radianLatitude--- Just (Latitude (DegreesLatitude (-74)) (Minutes 29) (Seconds 4.2481))------ >>> 1.5707963 ^? radianLatitude--- Just (Latitude (DegreesLatitude 89) (Minutes 59) (Seconds 59.9945))------ >>> 1.58 ^? radianLatitude--- Nothing------ >>> (-1.58) ^? radianLatitude--- Nothing------ >>> fmap (radianLatitude #) (do deg <- 7 ^? nDegreesLatitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLatitude)--- Just 0.12424320205794079------ >>> fmap (radianLatitude #) (do deg <- 89 ^? nDegreesLatitude; min <- 15 ^? nMinutes; sec <- 6 ^? nSeconds; (deg, min, sec) ^? dmsLatitude)--- Just 1.5577354462258057-radianLatitude ::-  Prism' Double Latitude-radianLatitude =-  iso (\n -> n * 180 / pi) (\n -> n * pi / 180) . fracLatitude--class HasLatitude t where-  latitude ::-    Lens' t Latitude--instance HasLatitude Latitude where-  latitude =-    id--instance HasDegreesLatitude Latitude where-  degreesLatitude =+instance (p ~ (->), Functor f) => AsDegreesLatitude p f Latitude where+  _DegreesLatitude =     lens (\(Latitude d _ _) -> d) (\(Latitude _ m s) d -> Latitude d m s) -instance HasMinutes Latitude where-  minutes =+instance (p ~ (->), Functor f) => AsMinutes p f Latitude where+  _Minutes =     lens (\(Latitude _ m _) -> m) (\(Latitude d _ s) m -> Latitude d m s) -instance HasSeconds Latitude where-  seconds =+instance (p ~ (->), Functor f) => AsSeconds p f Latitude where+  _Seconds =     lens (\(Latitude _ _ s) -> s) (\(Latitude d m _) s -> Latitude d m s)
src/Data/Geo/Coordinate/Longitude.hs view
@@ -1,26 +1,28 @@ {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}  module Data.Geo.Coordinate.Longitude(   Longitude-, HasLongitude(..)-, dmsLongitude-, fracLongitude-, radianLongitude+, AsLongitude(..)+, AsFracLongitude(..) ) where --import Control.Category(Category(id, (.)))-import Control.Lens(Iso', Prism', Lens', iso, prism', lens, (#), (^?))+import Control.Applicative(Applicative)+import Control.Category(Category(id))+import Control.Lens(Choice, Profunctor, Optic', Prism', iso, prism', lens, (#), (^?)) import Control.Monad(Monad(return)) import Data.Eq(Eq)-import Data.Geo.Coordinate.DegreesLongitude(HasDegreesLongitude(degreesLongitude), DegreesLongitude, nDegreesLongitude)-import Data.Geo.Coordinate.Minutes(HasMinutes(minutes), Minutes, nMinutes)-import Data.Geo.Coordinate.Seconds(HasSeconds(seconds), Seconds, nSeconds)+import Data.Geo.Coordinate.DegreesLongitude(DegreesLongitude, AsDegreesLongitude(_DegreesLongitude))+import Data.Geo.Coordinate.Minutes(AsMinutes(_Minutes), Minutes)+import Data.Geo.Coordinate.Seconds(AsSeconds(_Seconds), Seconds) import Data.Ord(Ord((<)))-import Prelude(Double, Show, Num((+), (*), (-), abs), Floating(pi), Fractional((/)), properFraction, fromIntegral)+import Prelude(Functor, Double, Show, Int, Num((+), (*), (-), abs), Fractional((/)), properFraction, fromIntegral)  -- $setup -- >>> import Prelude(Functor(..))+-- >>> import Data.Maybe  data Longitude =   Longitude@@ -29,139 +31,166 @@     Seconds   deriving (Eq, Ord, Show) +class AsLongitude p f s where+  _Longitude ::+    Optic' p f s Longitude++instance AsLongitude p f Longitude where+  _Longitude =+    id+ -- | An isomorphism on the triple of degrees longitude, minutes, seconds to a longitude. ----- >>> do deg <- 7 ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- >>> do deg <- (7 :: Int) ^? _DegreesLongitude; min <- (7 :: Int) ^? _Minutes; sec <- (7 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude 7) (Minutes 7) (Seconds 7.0000)) ----- >>> do deg <- 179 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- >>> do deg <- (179 :: Int) ^? _DegreesLongitude; min <- (59 :: Int) ^? _Minutes; sec <- (59 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude 179) (Minutes 59) (Seconds 59.0000)) ----- >>> do deg <- (-7) ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- >>> do deg <- (-7 :: Int) ^? _DegreesLongitude; min <- (7 :: Int) ^? _Minutes; sec <- (7 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude (-7)) (Minutes 7) (Seconds 7.0000)) ----- >>> do deg <- (-179) ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- >>> do deg <- (-179 :: Int) ^? _DegreesLongitude; min <- (59 :: Int) ^? _Minutes; sec <- (59 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude (-179)) (Minutes 59) (Seconds 59.0000)) ----- >>> do deg <- 180 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- >>> do deg <- (180 :: Int) ^? _DegreesLongitude; min <- (59 :: Int) ^? _Minutes; sec <- (59 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude -- Nothing ----- >>> do deg <- 179 ^? nDegreesLongitude; min <- 60 ^? nMinutes; sec <- 59 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- >>> do deg <- (179 :: Int) ^? _DegreesLongitude; min <- (60 :: Int) ^? _Minutes; sec <- (59 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude -- Nothing ----- >>> do deg <- 179 ^? nDegreesLongitude; min <- 59 ^? nMinutes; sec <- 60 ^? nSeconds; (deg, min, sec) ^? dmsLongitude+-- >>> do deg <- (179 :: Int) ^? _DegreesLongitude; min <- (59 :: Int) ^? _Minutes; sec <- (60 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude -- Nothing ----- >>> fmap (dmsLongitude #)  (7 ^? fracLongitude)+-- >>> fmap (\x -> _Longitude # x :: (DegreesLongitude, Minutes, Seconds))  (7 ^? fracLongitude :: Maybe Longitude) -- Just (DegreesLongitude 7,Minutes 0,Seconds 0.0000) ----- >>> fmap (dmsLongitude #)  (7.12 ^? fracLongitude)+-- >>> fmap (\x -> _Longitude # x :: (DegreesLongitude, Minutes, Seconds))  (7.12 ^? fracLongitude :: Maybe Longitude) -- Just (DegreesLongitude 7,Minutes 7,Seconds 12.0000)-dmsLongitude ::-  Iso' (DegreesLongitude, Minutes, Seconds) Longitude-dmsLongitude =-  iso (\(d, m, s) -> Longitude d m s) (\(Longitude d m s) -> (d, m, s))+instance (Profunctor p, Functor f) => AsLongitude p f (DegreesLongitude, Minutes, Seconds) where+  _Longitude =+    iso (\(d, m, s) -> Longitude d m s) (\(Longitude d m s) -> (d, m, s))  -- | A prism on longitude to a double between -180 and 180 exclusive. ----- >>> 7 ^? fracLongitude+-- >>> (7 :: Double) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude 7) (Minutes 0) (Seconds 0.0000)) ----- >>> (-7) ^? fracLongitude+-- >>> (-7 :: Double) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude (-7)) (Minutes 0) (Seconds 0.0000)) ----- >>> 7.12 ^? fracLongitude+-- >>> (7.12 :: Double) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude 7) (Minutes 7) (Seconds 12.0000)) ----- >>> (-7.12) ^? fracLongitude+-- >>> (-7.12 :: Double) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude (-7)) (Minutes 7) (Seconds 12.0000)) ----- >>> fmap (fracLongitude #) (7.12 ^? fracLongitude)+-- >>> fmap (\x -> _Longitude # x  :: Double) ((7.12 :: Double) ^? _Longitude :: Maybe Longitude) -- Just 7.12 ----- >>> fmap (fracLongitude #) ((-7.12) ^? fracLongitude)+-- >>> fmap (\x -> _Longitude # x :: Double) ((-7.12 :: Double) ^? _Longitude :: Maybe Longitude) -- Just (-7.12) ----- >>> 180 ^? fracLongitude+-- >>> (180 :: Double) ^? _Longitude :: Maybe Longitude -- Nothing ----- >>> (-180) ^? fracLongitude+-- >>> (-180 :: Double) ^? _Longitude :: Maybe Longitude -- Nothing ----- >>> 15.63791 ^? fracLongitude+-- >>> (15.63791 :: Double) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude 15) (Minutes 38) (Seconds 16.4760)) ----- >>> 179.1 ^? fracLongitude+-- >>> (179.1 :: Double) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude 179) (Minutes 5) (Seconds 60.0000)) ----- >>> 179.2 ^? fracLongitude+-- >>> (179.2 :: Double) ^? _Longitude :: Maybe Longitude -- Just (Longitude (DegreesLongitude 179) (Minutes 11) (Seconds 60.0000)) ----- >>> fmap (fracLongitude #) (do deg <- 7 ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude)+-- >>> fmap (\x -> _Longitude # x :: Double) (do deg <- (7 :: Int) ^? _DegreesLongitude; min <- (7 :: Int) ^? _Minutes; sec <- (7 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude) -- Just 7.118611111111111 ----- >>> fmap (fracLongitude #) (do deg <- 179 ^? nDegreesLongitude; min <- 15 ^? nMinutes; sec <- 6 ^? nSeconds; (deg, min, sec) ^? dmsLongitude)+-- >>> fmap (\x -> _Longitude # x :: Double) (do deg <- (179 :: Int) ^? _DegreesLongitude; min <- (15 :: Int) ^? _Minutes; sec <- (6 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude) -- Just 179.25166666666667-fracLongitude ::-  Prism' Double Longitude-fracLongitude =-  prism' (\(Longitude d m s) ->-    let p = fromIntegral (nDegreesLongitude # d)-        q = (fromIntegral (nMinutes # m) / 60) + (nSeconds # s) / 3600-    in (if p < 0 then (-) else (+)) p q)-    (\x -> let (d, z) = properFraction x-               (m, s) = properFraction ((z :: Double) * 60)-           in do d' <- d ^? nDegreesLongitude-                 m' <- abs m ^? nMinutes-                 s' <- (abs s * 60) ^? nSeconds-                 return (Longitude d' m' s'))+instance (Choice p, Applicative f) => AsLongitude p f Double where+  _Longitude =+    prism' (\(Longitude d m s) ->+      let p = fromIntegral (_DegreesLongitude # d :: Int)+          q = (fromIntegral (_Minutes # m :: Int) / 60) + (_Seconds # s) / 3600+      in (if p < 0 then (-) else (+)) p q)+      (\x -> let (d, z) = properFraction x+                 (m, s) = properFraction ((z :: Double) * 60)+             in do d' <- (d :: Int) ^? _DegreesLongitude+                   m' <- (abs m :: Int) ^? _Minutes+                   s' <- (abs s * 60) ^? _Seconds+                   return (Longitude d' m' s')) --- | A prism on longitude to a double between -π and π exclusive.++-- | A prism on longitude to a double between -180 and 180 exclusive.+class AsFracLongitude t where+  fracLongitude ::+    Prism' Double t++-- | A prism on longitude to a double between -180 and 180 exclusive. ----- >>> 0.2 ^? radianLongitude--- Just (Longitude (DegreesLongitude 11) (Minutes 27) (Seconds 32.9612))+-- >>> 7 ^? fracLongitude :: Maybe Longitude+-- Just (Longitude (DegreesLongitude 7) (Minutes 0) (Seconds 0.0000)) ----- >>> 1.3 ^? radianLongitude--- Just (Longitude (DegreesLongitude 74) (Minutes 29) (Seconds 4.2481))+-- >>> (-7) ^? fracLongitude :: Maybe Longitude+-- Just (Longitude (DegreesLongitude (-7)) (Minutes 0) (Seconds 0.0000)) ----- >>> (-1.3) ^? radianLongitude--- Just (Longitude (DegreesLongitude (-74)) (Minutes 29) (Seconds 4.2481))+-- >>> 7.12 ^? fracLongitude :: Maybe Longitude+-- Just (Longitude (DegreesLongitude 7) (Minutes 7) (Seconds 12.0000)) ----- >>> 3.14159 ^? radianLongitude--- Just (Longitude (DegreesLongitude 179) (Minutes 59) (Seconds 59.4527))+-- >>> (-7.12) ^? fracLongitude :: Maybe Longitude+-- Just (Longitude (DegreesLongitude (-7)) (Minutes 7) (Seconds 12.0000)) ----- >>> 3.15 ^? radianLongitude+-- >>> fmap (fracLongitude #) (7.12 ^? fracLongitude :: Maybe Longitude)+-- Just 7.12+--+-- >>> fmap (fracLongitude #) ((-7.12) ^? fracLongitude :: Maybe Longitude)+-- Just (-7.12)+--+-- >>> 180 ^? fracLongitude :: Maybe Longitude -- Nothing ----- >>> (-3.15) ^? radianLongitude+-- >>> (-180) ^? fracLongitude :: Maybe Longitude -- Nothing ----- >>> fmap (radianLongitude #) (do deg <- 7 ^? nDegreesLongitude; min <- 7 ^? nMinutes; sec <- 7 ^? nSeconds; (deg, min, sec) ^? dmsLongitude)--- Just 0.12424320205794079+-- >>> 15.63791 ^? fracLongitude :: Maybe Longitude+-- Just (Longitude (DegreesLongitude 15) (Minutes 38) (Seconds 16.4760)) ----- >>> fmap (radianLongitude #) (do deg <- 179 ^? nDegreesLongitude; min <- 15 ^? nMinutes; sec <- 6 ^? nSeconds; (deg, min, sec) ^? dmsLongitude)--- Just 3.1285317730207023-radianLongitude ::-  Prism' Double Longitude-radianLongitude =-  iso (\n -> n * 180 / pi) (\n -> n * pi / 180) . fracLongitude--class HasLongitude t where-  longitude ::-    Lens' t Longitude--instance HasLongitude Longitude where-  longitude =-    id+-- >>> 179.1 ^? fracLongitude :: Maybe Longitude+-- Just (Longitude (DegreesLongitude 179) (Minutes 5) (Seconds 60.0000))+--+-- >>> 179.2 ^? fracLongitude :: Maybe Longitude+-- Just (Longitude (DegreesLongitude 179) (Minutes 11) (Seconds 60.0000))+--+-- >>> fmap (fracLongitude #) (do deg <- (7 :: Int) ^? _DegreesLongitude; min <- (7 :: Int) ^? _Minutes; sec <- (7 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude)+-- Just 7.118611111111111+--+-- >>> fmap (fracLongitude #) (do deg <- (179 :: Int) ^? _DegreesLongitude; min <- (15 :: Int) ^? _Minutes; sec <- (6 :: Double) ^? _Seconds; (deg, min, sec) ^? _Longitude :: Maybe Longitude)+-- Just 179.25166666666667+instance AsFracLongitude Longitude where+  fracLongitude =+    prism' (\(Longitude d m s) ->+      let p = fromIntegral (_DegreesLongitude # d :: Int)+          q = (fromIntegral (_Minutes # m :: Int) / 60) + (_Seconds # s) / 3600+      in (if p < 0 then (-) else (+)) p q)+      (\x -> let (d, z) = properFraction x+                 (m, s) = properFraction ((z :: Double) * 60)+             in do d' <- (d :: Int) ^? _DegreesLongitude+                   m' <- (abs m :: Int) ^? _Minutes+                   s' <- (abs s * 60) ^? _Seconds+                   return (Longitude d' m' s')) -instance HasDegreesLongitude Longitude where-  degreesLongitude =+instance (p ~ (->), Functor f) => AsDegreesLongitude p f Longitude where+  _DegreesLongitude =     lens (\(Longitude d _ _) -> d) (\(Longitude _ m s) d -> Longitude d m s)--instance HasMinutes Longitude where-  minutes =+    +instance (p ~ (->), Functor f) => AsMinutes p f Longitude where+  _Minutes =     lens (\(Longitude _ m _) -> m) (\(Longitude d _ s) m -> Longitude d m s) -instance HasSeconds Longitude where-  seconds =+instance (p ~ (->), Functor f) => AsSeconds p f Longitude where+  _Seconds =     lens (\(Longitude _ _ s) -> s) (\(Longitude d m _) s -> Longitude d m s)
src/Data/Geo/Coordinate/Minutes.hs view
@@ -1,14 +1,16 @@ {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}  module Data.Geo.Coordinate.Minutes(   Minutes-, HasMinutes(..)-, nMinutes+, AsMinutes(..) , modMinutes ) where +import Control.Applicative(Applicative) import Control.Category(Category(id))-import Control.Lens(Prism', Lens', prism')+import Control.Lens(Optic', Choice, prism') import Data.Bool((&&)) import Data.Maybe(Maybe(Just, Nothing)) import Data.Eq(Eq)@@ -18,7 +20,7 @@ import Prelude(Show)  -- $setup--- >>> import Control.Lens((#), (^?))+-- >>> import Control.Lens((#), (^?), (^.)) -- >>> import Data.Foldable(all) -- >>> import Prelude(Eq(..)) @@ -26,9 +28,39 @@   Minutes Int   deriving (Eq, Ord, Show) --- | Construct minutes such that if the given value is out of bounds,--- a modulus is taken to keep it within 0 inclusive and 59 inclusive.+class AsMinutes p f s where+  _Minutes ::+    Optic' p f s Minutes++instance AsMinutes p f Minutes where+  _Minutes =+    id++-- | A prism on minutes to an integer between 0 and 59 inclusive. --+-- >>> (7 :: Int) ^? _Minutes+-- Just (Minutes 7)+--+-- >>> (0 :: Int) ^? _Minutes+-- Just (Minutes 0)+--+-- >>> (59 :: Int) ^? _Minutes+-- Just (Minutes 59)+--+-- >>> (60 :: Int) ^? _Minutes+-- Nothing+--+-- prop> all (\m -> _Minutes # m == (n :: Int)) (n ^? _Minutes)+instance (Choice p, Applicative f) => AsMinutes p f Int where+  _Minutes =+    prism'+      (\(Minutes i) -> i)+      (\i -> if i >= 0 && i < 60+               then Just (Minutes i)+               else Nothing)       ++-- | Setting a value `>= 60` will get that value `(`mod` 60)`.+-- -- >>> modMinutes 7 -- Minutes 7 --@@ -38,45 +70,13 @@ -- >>> modMinutes 60 -- Minutes 0 ----- >>> modMinutes 61+-- >>> modMinutes 1 -- Minutes 1 -- -- >>> modMinutes 59--- Minutes 59+-- Minutes 59  modMinutes ::   Int   -> Minutes modMinutes x =   Minutes (x `mod'` 60)---- | A prism on minutes to an integer between 0 and 59 inclusive.------ >>> 7 ^? nMinutes--- Just (Minutes 7)------ >>> 0 ^? nMinutes--- Just (Minutes 0)------ >>> 59 ^? nMinutes--- Just (Minutes 59)------ >>> 60 ^? nMinutes--- Nothing------ prop> all (\m -> nMinutes # m == n) (n ^? nMinutes)-nMinutes ::-  Prism' Int Minutes-nMinutes =-  prism'-    (\(Minutes i) -> i)-    (\i -> if i >= 0 && i < 60-             then Just (Minutes i)-             else Nothing)--class HasMinutes t where-  minutes ::-    Lens' t Minutes--instance HasMinutes Minutes where-  minutes =-    id
src/Data/Geo/Coordinate/Seconds.hs view
@@ -1,14 +1,16 @@ {-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}  module Data.Geo.Coordinate.Seconds(   Seconds-, HasSeconds(..)+, AsSeconds(..) , modSeconds-, nSeconds ) where +import Control.Applicative(Applicative) import Control.Category(Category(id))-import Control.Lens(Prism', Lens', prism')+import Control.Lens(prism', Optic', Choice) import Data.Bool((&&)) import Data.Eq(Eq) import Data.Fixed(mod')@@ -19,7 +21,7 @@ import Text.Printf(printf)  -- $setup--- >>> import Control.Lens((#), (^?))+-- >>> import Control.Lens((#), (^?), (^.)) -- >>> import Data.Foldable(all) -- >>> import Prelude(Eq(..)) @@ -33,9 +35,42 @@   showsPrec n (Seconds d) =     showParen (n > 10) (showString ("Seconds " ++ printf "%0.4f" d)) --- | Construct seconds such that if the given value is out of bounds,--- a modulus is taken to keep it within 0 inclusive and 60 exclusive.+class AsSeconds p f s where+  _Seconds ::+    Optic' p f s Seconds++instance AsSeconds p f Seconds where+  _Seconds =+    id++-- | A prism on seconds to a double between 0 inclusive and 60 exclusive. --+-- >>> (7 :: Double) ^? _Seconds+-- Just (Seconds 7.0000)+--+-- >>> (0 :: Double) ^? _Seconds+-- Just (Seconds 0.0000)+--+-- >>> (59 :: Double) ^? _Seconds+-- Just (Seconds 59.0000)+--+-- >>> (59.99 :: Double) ^? _Seconds+-- Just (Seconds 59.9900)+--+-- >>> (60 :: Double) ^? _Seconds+-- Nothing+--+-- prop> all (\m -> _Seconds # m == (n :: Double)) (n ^? _Seconds)+instance (Choice p, Applicative f) => AsSeconds p f Double where+  _Seconds =+    prism'+      (\(Seconds d) -> d)+      (\d -> if d >= 0 && d < 60+               then Just (Seconds d)+               else Nothing)++-- | Setting a value `>= 60` will get that value `(`mod` 60)`.+-- -- >>> modSeconds 7 -- Seconds 7.0000 --@@ -58,38 +93,3 @@   -> Seconds modSeconds x =   Seconds (x `mod'` 60)---- | A prism on seconds to a double between 0 inclusive and 60 exclusive.------ >>> 7 ^? nSeconds--- Just (Seconds 7.0000)------ >>> 0 ^? nSeconds--- Just (Seconds 0.0000)------ >>> 59 ^? nSeconds--- Just (Seconds 59.0000)------ >>> 59.99 ^? nSeconds--- Just (Seconds 59.9900)------ >>> 60 ^? nSeconds--- Nothing------ prop> all (\m -> nSeconds # m == n) (n ^? nSeconds)-nSeconds ::-  Prism' Double Seconds-nSeconds =-  prism'-    (\(Seconds d) -> d)-    (\d -> if d >= 0 && d < 60-             then Just (Seconds d)-             else Nothing)--class HasSeconds t where-  seconds ::-    Lens' t Seconds--instance HasSeconds Seconds where-  seconds =-    id