From 7f858e0d405286bf8d6cb1a1a28d3f5c7fb6ab91 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Wed, 2 Dec 2015 11:14:35 -0500 Subject: [PATCH 01/19] Added package flags for optional instances that require additional dependencies. --- dimensional.cabal | 53 +++++++++++++++ src/Numeric/Units/Dimensional/Functor.hs | 5 +- src/Numeric/Units/Dimensional/Internal.hs | 83 ++++++++++++++++++----- 3 files changed, 124 insertions(+), 17 deletions(-) diff --git a/dimensional.cabal b/dimensional.cabal index 3f322f36..62185182 100644 --- a/dimensional.cabal +++ b/dimensional.cabal @@ -36,6 +36,36 @@ extra-source-files: README.md, examples/README, examples/GM.lhs +flag functor + description: Provide a Functor instance for Quantity. + default: False + manual: True + +flag aeson + description: Provide instances for use with the aeson package. + default: False + manual: True + +flag binary + description: Provide instances for use with the binary package. + default: False + manual: True + +flag cereal + description: Provide instances for use with the cereal package. + default: False + manual: True + +flag linear + description: Provide instances for use with the linear package. + default: False + manual: True + +flag vector-space + description: Provide instances for use with the vector-space package. + default: False + manual: True + source-repository head type: git location: https://github.com/bjornbm/dimensional/ @@ -66,6 +96,29 @@ library other-modules: Numeric.Units.Dimensional.Internal, Numeric.Units.Dimensional.UnitNames.Internal + if flag(functor) + cpp-options: -DFUNCTOR + + if flag(aeson) + build-depends: aeson >= 0.10 && < 1 + cpp-options: -DUSE_AESON + + if flag(binary) + build-depends: binary >= 0.7 && < 1 + cpp-options: -DUSE_BINARY + + if flag(cereal) + build-depends: cereal >= 0.5 && <1 + cpp-options: -DUSE_CEREAL + + if flag(linear) + build-depends: linear >= 1.19 && < 2 + cpp-options: -DUSE_LINEAR + + if flag(vector-space) + build-depends: vector-space >= 0.10 && < 1 + cpp-options: -DUSE_VECTOR_SPACE + test-suite tests type: exitcode-stdio-1.0 main-is: Test.hs diff --git a/src/Numeric/Units/Dimensional/Functor.hs b/src/Numeric/Units/Dimensional/Functor.hs index 2a232c54..3628d31c 100644 --- a/src/Numeric/Units/Dimensional/Functor.hs +++ b/src/Numeric/Units/Dimensional/Functor.hs @@ -25,8 +25,10 @@ Note that, while this instance overlaps with that given for 'Dimensionless', it Note that this is an orphan instance. -} -module Numeric.Units.Dimensional.Functor where +module Numeric.Units.Dimensional.Functor {-# DEPRECATED "This orphan instance is being eliminated in favor of a package flag, functor, which creates it as a proper instance." #-} where +-- If we already have this instance, we won't declare it again. +#if !(FUNCTOR || USE_LINEAR) import Numeric.Units.Dimensional -- | A 'Functor' instance for 'Dimensional'. @@ -38,3 +40,4 @@ import Numeric.Units.Dimensional -- Note that this is an orphan instance. instance {-# OVERLAPPING #-} (KnownVariant v) => Functor (Dimensional v d) where fmap = dmap +#endif diff --git a/src/Numeric/Units/Dimensional/Internal.hs b/src/Numeric/Units/Dimensional/Internal.hs index c044e777..13fd0a17 100644 --- a/src/Numeric/Units/Dimensional/Internal.hs +++ b/src/Numeric/Units/Dimensional/Internal.hs @@ -4,6 +4,7 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} -- for Vector instances only {-# LANGUAGE RankNTypes #-} @@ -46,9 +47,29 @@ import qualified Data.Vector.Unboxed.Base as U import Prelude ( Show, Eq(..), Ord, Bounded(..), Num, Fractional, Functor , String, Maybe(..) - , (.), ($), (++), (+), (/) + , (.), ($), (++) , show, otherwise, undefined, error, fmap ) +import qualified Prelude as P + +-- Optional imports when certain package flags are enabled +#if USE_AESON +import qualified Data.Aeson +#endif +#if USE_BINARY +import qualified Data.Binary +#endif +#if USE_CEREAL +import qualified Data.Serialize +#endif +#if USE_LINEAR +import qualified Linear.Affine +import qualified Linear.Vector +#endif +#if USE_VECTOR_SPACE +import qualified Data.AdditiveGroup +import qualified Data.VectorSpace +#endif -- | A unit of measurement. type Unit (m :: Metricality) = Dimensional ('DUnit m) @@ -99,6 +120,48 @@ instance (Typeable m) => KnownVariant ('DUnit m) where injectValue _ _ = error "Shouldn't be reachable. Needed to name a quantity." dmap f (Unit n e x) = Unit n e (f x) +{- + +If the FUNCTOR flag is set or is required by another flag, we provide a Functor instance for all dimensional values. +Regardless, we provide a functor instance for dimensionless quantities. + +-} +#if FUNCTOR || USE_LINEAR +instance (KnownVariant v) => Functor (Dimensional v d) where + fmap = dmap +#else +instance Functor (Quantity DOne) where + fmap = dmap +#endif + +#if USE_AESON +#endif + +#if USE_BINARY +deriving instance (Data.Binary.Binary a) => Data.Binary.Binary (Quantity d a) +#endif + +#if USE_CEREAL +deriving instance (Data.Serialize.Serialize a) => Data.Serialize.Serialize (Quantity d a) +#endif + +#if USE_LINEAR +#endif + +#if USE_VECTOR_SPACE +instance (Num a) => Data.AdditiveGroup.AdditiveGroup (Quantity d a) where + zeroV = mempty + (^+^) = mappend + negateV = liftQ P.negate + +instance (Num a) => Data.VectorSpace.VectorSpace (Quantity d a) where + type Scalar (Quantity d a) = Quantity DOne a + (*^) = liftQ2 (P.*) + +instance (Num a) => Data.VectorSpace.InnerSpace (Quantity DOne a) where + (<.>) = liftQ2 (P.*) +#endif + -- GHC is somewhat unclear about why, but it won't derive this instance, so we give it explicitly. instance (Bounded a) => Bounded (Quantity d a) where minBound = Quantity minBound @@ -115,19 +178,7 @@ we will define a monoid instance that adds. -- | 'Quantity's of a given 'Dimension' form a 'Monoid' under addition. instance (Num a) => Monoid (Quantity d a) where mempty = Quantity 0 - mappend = liftQ2 (+) - -{- - -= Dimensionless = - -For dimensionless quantities pretty much any operation is applicable. -We provide this freedom by making 'Dimensionless' an instance of -'Functor'. --} - -instance Functor (Quantity DOne) where - fmap = dmap + mappend = liftQ2 (P.+) instance (KnownDimension d) => HasDimension (Dimensional v d a) where dimension _ = dimension (Proxy :: Proxy d) @@ -197,8 +248,8 @@ instance (KnownDimension d, Show a, Fractional a) => Show (Quantity d a) where -- | Shows the value of a 'Quantity' expressed in a specified 'Unit' of the same 'Dimension'. showIn :: (KnownDimension d, Show a, Fractional a) => Unit m d a -> Quantity d a -> String -showIn (Unit n _ y) (Quantity x) | Name.weaken n == nOne = show (x / y) - | otherwise = (show (x / y)) ++ " " ++ (show n) +showIn (Unit n _ y) (Quantity x) | Name.weaken n == nOne = show (x P./ y) + | otherwise = (show (x P./ y)) ++ " " ++ (show n) instance (KnownDimension d, Show a) => Show (Unit m d a) where show (Unit n e x) = "The unit " ++ show n ++ ", with value " ++ show e ++ " (or " ++ show x ++ ")" From a0f0bd2ff496efce17c6868b63ba7f40ed196e66 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Wed, 2 Dec 2015 13:21:48 -0500 Subject: [PATCH 02/19] Added aeson instances. --- src/Numeric/Units/Dimensional/Internal.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Numeric/Units/Dimensional/Internal.hs b/src/Numeric/Units/Dimensional/Internal.hs index 13fd0a17..5fd3bc69 100644 --- a/src/Numeric/Units/Dimensional/Internal.hs +++ b/src/Numeric/Units/Dimensional/Internal.hs @@ -135,6 +135,9 @@ instance Functor (Quantity DOne) where #endif #if USE_AESON +deriving instance (Data.Aeson.ToJSON a) => Data.Aeson.ToJSON (Quantity d a) + +deriving instance (Data.Aeson.FromJSON a) => Data.Aeson.FromJSON (Quantity d a) #endif #if USE_BINARY From 1f6605405b9ac7076829082998d3e55036e077a4 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Thu, 24 Dec 2015 11:39:57 -0500 Subject: [PATCH 03/19] Added instances for the linear package. --- src/Numeric/Units/Dimensional/Internal.hs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Numeric/Units/Dimensional/Internal.hs b/src/Numeric/Units/Dimensional/Internal.hs index 5b8995ce..650f1cc4 100644 --- a/src/Numeric/Units/Dimensional/Internal.hs +++ b/src/Numeric/Units/Dimensional/Internal.hs @@ -149,6 +149,18 @@ deriving instance (Data.Serialize.Serialize a) => Data.Serialize.Serialize (Quan #endif #if USE_LINEAR +instance Linear.Vector.Additive (Quantity d) where + zero = mempty + (^+^) = liftQ2 (P.+) + (^-^) = liftQ2 (P.-) + liftU2 = liftQ2 + liftI2 f (Quantity x) (Quantity y) = Quantity $ f x y + +instance Linear.Affine.Affine (Quantity d) where + type Diff (Quantity d) = Quantity d + (.-.) = (Linear.Vector.^-^) + (.+^) = (Linear.Vector.^+^) + (.-^) = (Linear.Vector.^-^) #endif #if USE_VECTOR_SPACE From c2e1355c492211bbd9cfbed82b0779b344483047 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Thu, 24 Dec 2015 12:19:48 -0500 Subject: [PATCH 04/19] Documentation and changelog. --- CHANGELOG.md | 6 ++++++ README.md | 17 +++++++++++++++++ src/Numeric/Units/Dimensional.hs | 3 ++- src/Numeric/Units/Dimensional/Functor.hs | 2 +- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08dbb873..174bd3ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,12 @@ vNext module which may cause name collisions. * Breaking: Removed exports of `nMeter`, `nSecond`, `kilo`, etc from Numeric.Units.Dimensional.UnitNames. Access these instead by inspecting the relevant units or prefixes. +* Deprecated: The `Numeric.Units.Dimensional.Functor` module and the orphan instance + it provides were deprecated in favor of a package flag, `functor`, which provides the + same instance but doesn't orphan it. +* Added package flags `aeson`, `binary`, `cereal`, `linear`, and `vector-space` enabling + optional dependencies on the packages of the same names to provide instances of widely + used classes from those packages. * Added `Data`, `Generic`, `Typeable` and `NFData` instances for many ancillary types. * Added `unQuantity` to the Coercion module to ease unwrapping without introducing ambiguous type variables. diff --git a/README.md b/README.md index 86813104..2e16a55b 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,23 @@ main = do putStrLn $ "The journey requires " ++ show wholeSeconds ++ " seconds, rounded up to the nearest second." ``` +## Package Flags + +Package flags are available which enable us to provide instances for Quantity that are useful to interoperate with various popular packages without burdening all users with those +dependencies or creating orphan instances. + +To install with a `Functor` instance for quantities of all dimensions, instead of just +for dimensionless quantities, use: + +`cabal install dimensional -f functor` + +To install with `ToJSON` and `FromJSON` instances for `Quantity`, use: + +`cabal install dimensional -f aeson` + +Similarly the `binary`, `cereal`, `linear`, and `vector-space` flags enable appropriate +instances for use with the packages of the same names. + ## Contributing For project information (issues, updates, wiki, examples) see: diff --git a/src/Numeric/Units/Dimensional.hs b/src/Numeric/Units/Dimensional.hs index 6bbaa17e..58ab93ff 100644 --- a/src/Numeric/Units/Dimensional.hs +++ b/src/Numeric/Units/Dimensional.hs @@ -640,7 +640,8 @@ tau = _2 * pi We intentionally decline to provide a 'Functor' instance for 'Dimensional' because its use breaks the abstraction of physical dimensions. -If you feel your work requires this instance, it is provided as an orphan in "Numeric.Units.Dimensional.Functor". +If you feel your work requires this instance, it is provided by enabling the `functor` package +flag when installing the package. -} diff --git a/src/Numeric/Units/Dimensional/Functor.hs b/src/Numeric/Units/Dimensional/Functor.hs index 3628d31c..1e8d4fb9 100644 --- a/src/Numeric/Units/Dimensional/Functor.hs +++ b/src/Numeric/Units/Dimensional/Functor.hs @@ -25,7 +25,7 @@ Note that, while this instance overlaps with that given for 'Dimensionless', it Note that this is an orphan instance. -} -module Numeric.Units.Dimensional.Functor {-# DEPRECATED "This orphan instance is being eliminated in favor of a package flag, functor, which creates it as a proper instance." #-} where +module Numeric.Units.Dimensional.Functor {-# DEPRECATED "This orphan instance is being eliminated, along with the module packaging it, in favor of a package flag, functor, which creates it as a proper instance." #-} where -- If we already have this instance, we won't declare it again. #if !(FUNCTOR || USE_LINEAR) From 6937abd58ccd36cd103f7751fb55833d33892d4c Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Mon, 28 Dec 2015 17:53:20 -0500 Subject: [PATCH 05/19] Added serialization instances for dynamic dimensions and dynamic quantities. --- .../Units/Dimensional/Dimensions/TermLevel.hs | 28 +++++++++++ src/Numeric/Units/Dimensional/Dynamic.hs | 49 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs b/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs index bde7bc16..469bd4fc 100644 --- a/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs +++ b/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs @@ -1,9 +1,12 @@ {-# OPTIONS_HADDOCK not-home, show-extensions #-} {-# LANGUAGE BangPatterns #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE DefaultSignatures #-} +{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE StandaloneDeriving #-} {- | Copyright : Copyright (C) 2006-2015 Bjorn Buckwalter @@ -40,6 +43,17 @@ import GHC.Generics import Prelude (id, (+), (-), (.), Int, Show, Eq, Ord, Maybe(..)) import qualified Prelude as P +-- Optional imports when certain package flags are enabled +#if USE_AESON +import qualified Data.Aeson +#endif +#if USE_BINARY +import qualified Data.Binary +#endif +#if USE_CEREAL +import qualified Data.Serialize +#endif + -- | A physical dimension, encoded as 7 integers, representing a factorization of the dimension into the -- 7 SI base dimensions. By convention they are stored in the same order as -- in the 'Numeric.Units.Dimensional.Dimensions.TypeLevel.Dimension' data kind. @@ -54,6 +68,20 @@ instance Monoid Dimension' where mempty = dOne mappend = (*) +#if USE_AESON +deriving instance Data.Aeson.ToJSON Dimension' + +deriving instance Data.Aeson.FromJSON Dimension' +#endif + +#if USE_BINARY +deriving instance Data.Binary.Binary Dimension' +#endif + +#if USE_CEREAL +deriving instance Data.Serialize.Serialize Dimension' +#endif + -- | Dimensional values, or those that are only possibly dimensional, inhabit this class, -- which allows access to a term-level representation of their dimension. class HasDynamicDimension a where diff --git a/src/Numeric/Units/Dimensional/Dynamic.hs b/src/Numeric/Units/Dimensional/Dynamic.hs index 9e9a5bd0..d02518e9 100644 --- a/src/Numeric/Units/Dimensional/Dynamic.hs +++ b/src/Numeric/Units/Dimensional/Dynamic.hs @@ -9,14 +9,18 @@ Defines types for manipulation of units and quantities without phantom types for their dimensions. -} +{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE StandaloneDeriving #-} module Numeric.Units.Dimensional.Dynamic ( @@ -53,6 +57,18 @@ import qualified Numeric.Units.Dimensional.UnitNames as N import Numeric.Units.Dimensional.Dimensions.TermLevel (HasDynamicDimension(..)) import qualified Numeric.Units.Dimensional.Dimensions.TermLevel as D +-- Optional imports when certain package flags are enabled +#if USE_AESON +import qualified Data.Aeson +import qualified Data.Monoid +#endif +#if USE_BINARY +import qualified Data.Binary +#endif +#if USE_CEREAL +import qualified Data.Serialize +#endif + -- | The class of types that can be used to model 'Quantity's that are certain to have a value with -- some dimension. class Demoteable (q :: * -> *) where @@ -120,6 +136,25 @@ instance Num a => Monoid (AnyQuantity a) where mempty = demoteQuantity (1 Dim.*~ one) mappend (AnyQuantity d1 a1) (AnyQuantity d2 a2) = AnyQuantity (d1 D.* d2) (a1 P.* a2) +#if USE_AESON +instance (Data.Aeson.ToJSON a) => Data.Aeson.ToJSON (AnyQuantity a) where + toJSON (AnyQuantity d a) = Data.Aeson.object ["dimension" Data.Aeson..= d, "value" Data.Aeson..= a] + toEncoding (AnyQuantity d a) = Data.Aeson.pairs ("dimension" Data.Aeson..= d Data.Monoid.<> "value" Data.Aeson..= a) + +instance (Data.Aeson.FromJSON a) => Data.Aeson.FromJSON (AnyQuantity a) where + parseJSON (Data.Aeson.Object v) = AnyQuantity P.<$> + v Data.Aeson..: "dimension" P.<*> + v Data.Aeson..: "value" + parseJSON _ = Data.Monoid.mempty +#endif + +#if USE_BINARY +deriving instance (Data.Binary.Binary a) => Data.Binary.Binary (AnyQuantity a) +#endif + +#if USE_CEREAL +deriving instance (Data.Serialize.Serialize a) => Data.Serialize.Serialize (AnyQuantity a) +#endif -- | Possibly a 'Quantity' whose 'Dimension' is only known dynamically. -- @@ -188,6 +223,20 @@ instance Num a => Monoid (DynQuantity a) where mempty = demoteQuantity (1 Dim.*~ one) mappend = (P.*) +#if USE_AESON +deriving instance (Data.Aeson.ToJSON a) => Data.Aeson.ToJSON (DynQuantity a) + +deriving instance (Data.Aeson.FromJSON a) => Data.Aeson.FromJSON (DynQuantity a) +#endif + +#if USE_BINARY +deriving instance (Data.Binary.Binary a) => Data.Binary.Binary (DynQuantity a) +#endif + +#if USE_CEREAL +deriving instance (Data.Serialize.Serialize a) => Data.Serialize.Serialize (DynQuantity a) +#endif + -- Lifts a function which is only valid on dimensionless quantities into a function on DynQuantitys. liftDimensionless :: (a -> a) -> DynQuantity a -> DynQuantity a liftDimensionless = liftDQ (matching D.dOne) From a107c7e041caf0663cceccc97ffc57162800979f Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 29 Dec 2015 09:46:09 -0500 Subject: [PATCH 06/19] Changed to not require DeriveAnyClass and to suppress warnings. --- .../Units/Dimensional/Dimensions/TermLevel.hs | 14 ++++++++------ src/Numeric/Units/Dimensional/Dynamic.hs | 16 ++++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs b/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs index 469bd4fc..699ba1bc 100644 --- a/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs +++ b/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs @@ -3,10 +3,8 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} {-# LANGUAGE DefaultSignatures #-} -{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE StandaloneDeriving #-} {- | Copyright : Copyright (C) 2006-2015 Bjorn Buckwalter @@ -69,17 +67,21 @@ instance Monoid Dimension' where mappend = (*) #if USE_AESON -deriving instance Data.Aeson.ToJSON Dimension' +-- This instance only needs a body because an incorrect MINIMAL pragma in aeson-0.10 leads to +-- a warning if you omit it. +instance Data.Aeson.ToJSON Dimension' where + toJSON = Data.Aeson.genericToJSON Data.Aeson.defaultOptions + toEncoding = Data.Aeson.genericToEncoding Data.Aeson.defaultOptions -deriving instance Data.Aeson.FromJSON Dimension' +instance Data.Aeson.FromJSON Dimension' #endif #if USE_BINARY -deriving instance Data.Binary.Binary Dimension' +instance Data.Binary.Binary Dimension' #endif #if USE_CEREAL -deriving instance Data.Serialize.Serialize Dimension' +instance Data.Serialize.Serialize Dimension' #endif -- | Dimensional values, or those that are only possibly dimensional, inhabit this class, diff --git a/src/Numeric/Units/Dimensional/Dynamic.hs b/src/Numeric/Units/Dimensional/Dynamic.hs index d02518e9..0854e6b8 100644 --- a/src/Numeric/Units/Dimensional/Dynamic.hs +++ b/src/Numeric/Units/Dimensional/Dynamic.hs @@ -11,7 +11,6 @@ Defines types for manipulation of units and quantities without phantom types for {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} @@ -20,7 +19,6 @@ Defines types for manipulation of units and quantities without phantom types for {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE StandaloneDeriving #-} module Numeric.Units.Dimensional.Dynamic ( @@ -149,11 +147,11 @@ instance (Data.Aeson.FromJSON a) => Data.Aeson.FromJSON (AnyQuantity a) where #endif #if USE_BINARY -deriving instance (Data.Binary.Binary a) => Data.Binary.Binary (AnyQuantity a) +instance (Data.Binary.Binary a) => Data.Binary.Binary (AnyQuantity a) #endif #if USE_CEREAL -deriving instance (Data.Serialize.Serialize a) => Data.Serialize.Serialize (AnyQuantity a) +instance (Data.Serialize.Serialize a) => Data.Serialize.Serialize (AnyQuantity a) #endif -- | Possibly a 'Quantity' whose 'Dimension' is only known dynamically. @@ -224,17 +222,19 @@ instance Num a => Monoid (DynQuantity a) where mappend = (P.*) #if USE_AESON -deriving instance (Data.Aeson.ToJSON a) => Data.Aeson.ToJSON (DynQuantity a) +instance (Data.Aeson.ToJSON a) => Data.Aeson.ToJSON (DynQuantity a) where + toJSON = Data.Aeson.genericToJSON Data.Aeson.defaultOptions + toEncoding = Data.Aeson.genericToEncoding Data.Aeson.defaultOptions -deriving instance (Data.Aeson.FromJSON a) => Data.Aeson.FromJSON (DynQuantity a) +instance (Data.Aeson.FromJSON a) => Data.Aeson.FromJSON (DynQuantity a) #endif #if USE_BINARY -deriving instance (Data.Binary.Binary a) => Data.Binary.Binary (DynQuantity a) +instance (Data.Binary.Binary a) => Data.Binary.Binary (DynQuantity a) #endif #if USE_CEREAL -deriving instance (Data.Serialize.Serialize a) => Data.Serialize.Serialize (DynQuantity a) +instance (Data.Serialize.Serialize a) => Data.Serialize.Serialize (DynQuantity a) #endif -- Lifts a function which is only valid on dimensionless quantities into a function on DynQuantitys. From e3a4a2ef50a72b07374a1c07746b208de0cdc67b Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 29 Dec 2015 10:26:35 -0500 Subject: [PATCH 07/19] Documentation. --- src/Numeric/Units/Dimensional/Dynamic.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Numeric/Units/Dimensional/Dynamic.hs b/src/Numeric/Units/Dimensional/Dynamic.hs index 0854e6b8..0f30ad27 100644 --- a/src/Numeric/Units/Dimensional/Dynamic.hs +++ b/src/Numeric/Units/Dimensional/Dynamic.hs @@ -222,6 +222,8 @@ instance Num a => Monoid (DynQuantity a) where mappend = (P.*) #if USE_AESON +-- This instance only needs a body because an incorrect MINIMAL pragma in aeson-0.10 leads to +-- a warning if you omit it. instance (Data.Aeson.ToJSON a) => Data.Aeson.ToJSON (DynQuantity a) where toJSON = Data.Aeson.genericToJSON Data.Aeson.defaultOptions toEncoding = Data.Aeson.genericToEncoding Data.Aeson.defaultOptions From c3f5a16071fa30321e1c73901d04bec00065ae69 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 29 Dec 2015 10:48:58 -0500 Subject: [PATCH 08/19] Added various flag combinations to build matrix. --- .travis.yml | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 76f45ff8..3d196041 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,12 +16,30 @@ matrix: - env: CABALVER=1.18 GHCVER=7.8.4 compiler: ": #GHC 7.8.4" addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4], sources: [hvr-ghc]}} - - env: CABALVER=1.22 GHCVER=7.10.2 - compiler: ": #GHC 7.10.2" - addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.2], sources: [hvr-ghc]}} - env: CABALVER=1.22 GHCVER=7.10.3 compiler: ": #GHC 7.10.3" addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} + - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="functor" + compiler: ": #GHC 7.10.3" + addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} + - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="aeson" + compiler: ": #GHC 7.10.3" + addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} + - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="binary" + compiler: ": #GHC 7.10.3" + addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} + - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="cereal" + compiler: ": #GHC 7.10.3" + addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} + - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="linear" + compiler: ": #GHC 7.10.3" + addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} + - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="vector-space" + compiler: ": #GHC 7.10.3" + addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} + - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="functor aeson binary cereal linear vector-space" + compiler: ": #GHC 7.10.3" + addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} before_install: - unset CC @@ -37,7 +55,7 @@ install: fi - travis_retry cabal update -v - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config - - cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt + - cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS --dry -v > installplan.txt - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt # check whether current requested install-plan matches cached package-db snapshot @@ -67,7 +85,7 @@ install: # any command which exits with a non-zero exit code causes the build to fail. script: - if [ -f configure.ac ]; then autoreconf -i; fi - - cabal configure --enable-tests --enable-benchmarks -v2 # -v2 provides useful information for debugging + - cabal configure --enable-tests --enable-benchmarks --flags $FLAGS -v2 # -v2 provides useful information for debugging - cabal build # this builds all libraries and executables (including tests/benchmarks) - cabal test --show-details=always - cabal haddock From 5284e29f1a1c64cbc3a8e53593741592389da206 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 29 Dec 2015 11:10:33 -0500 Subject: [PATCH 09/19] Changes to diagnose flag build errors. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3d196041..3aebe1d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,10 +13,10 @@ before_cache: matrix: include: - - env: CABALVER=1.18 GHCVER=7.8.4 + - env: CABALVER=1.18 GHCVER=7.8.4 FLAGS="" compiler: ": #GHC 7.8.4" addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4], sources: [hvr-ghc]}} - - env: CABALVER=1.22 GHCVER=7.10.3 + - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="" compiler: ": #GHC 7.10.3" addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="functor" @@ -55,7 +55,7 @@ install: fi - travis_retry cabal update -v - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config - - cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS --dry -v > installplan.txt + - cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS --allow-newer=binary --dry -v > installplan.txt - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt # check whether current requested install-plan matches cached package-db snapshot @@ -85,7 +85,7 @@ install: # any command which exits with a non-zero exit code causes the build to fail. script: - if [ -f configure.ac ]; then autoreconf -i; fi - - cabal configure --enable-tests --enable-benchmarks --flags $FLAGS -v2 # -v2 provides useful information for debugging + - cabal configure --enable-tests --enable-benchmarks --flags $FLAGS -v # -v provides useful information for debugging - cabal build # this builds all libraries and executables (including tests/benchmarks) - cabal test --show-details=always - cabal haddock From bbbbf3fb9efde1a5bc58d4caa8d72aca8f6a8dd4 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 29 Dec 2015 11:39:33 -0500 Subject: [PATCH 10/19] Attempted to fix issues with flag builds. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3aebe1d6..9bc597c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -69,7 +69,7 @@ install: echo "cabal build-cache MISS"; rm -rf $HOME/.cabsnap; mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin; - cabal install --only-dependencies --enable-tests --enable-benchmarks; + cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS --allow-newer=binary; fi # snapshot package-db on cache miss From 4fabbc9cffa46f641add067aaaef7d7f12ebb40c Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 29 Dec 2015 12:24:11 -0500 Subject: [PATCH 11/19] Allow failure of combination build (currently happening due to conflicting versions on hackage). Consider fixing via #127. --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9bc597c9..4a5813f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,6 +40,8 @@ matrix: - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="functor aeson binary cereal linear vector-space" compiler: ": #GHC 7.10.3" addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}} + allow_failures: + - env: CABALVER=1.22 GHCVER=7.10.3 FLAGS="functor aeson binary cereal linear vector-space" before_install: - unset CC @@ -55,7 +57,7 @@ install: fi - travis_retry cabal update -v - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config - - cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS --allow-newer=binary --dry -v > installplan.txt + - cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS --dry -v > installplan.txt - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt # check whether current requested install-plan matches cached package-db snapshot @@ -69,7 +71,7 @@ install: echo "cabal build-cache MISS"; rm -rf $HOME/.cabsnap; mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin; - cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS --allow-newer=binary; + cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS; fi # snapshot package-db on cache miss From a1edf32cffd3ebdff380b2129a255218c76c0c56 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 29 Dec 2015 12:44:16 -0500 Subject: [PATCH 12/19] Attempted to fix issue with builds that set no flags. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4a5813f3..0f88e44d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,7 +57,7 @@ install: fi - travis_retry cabal update -v - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config - - cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS --dry -v > installplan.txt + - cabal install --only-dependencies --enable-tests --enable-benchmarks --flags=$FLAGS --dry -v > installplan.txt - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt # check whether current requested install-plan matches cached package-db snapshot @@ -87,7 +87,7 @@ install: # any command which exits with a non-zero exit code causes the build to fail. script: - if [ -f configure.ac ]; then autoreconf -i; fi - - cabal configure --enable-tests --enable-benchmarks --flags $FLAGS -v # -v provides useful information for debugging + - cabal configure --enable-tests --enable-benchmarks --flags=$FLAGS -v # -v provides useful information for debugging - cabal build # this builds all libraries and executables (including tests/benchmarks) - cabal test --show-details=always - cabal haddock From 6872e3580f199533cfb937074cc4d1b12e73cb5b Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Thu, 31 Dec 2015 14:53:36 -0500 Subject: [PATCH 13/19] Added metric instance for dimensionless quantities. --- src/Numeric/Units/Dimensional/Internal.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Numeric/Units/Dimensional/Internal.hs b/src/Numeric/Units/Dimensional/Internal.hs index 650f1cc4..bc4c5919 100644 --- a/src/Numeric/Units/Dimensional/Internal.hs +++ b/src/Numeric/Units/Dimensional/Internal.hs @@ -64,6 +64,7 @@ import qualified Data.Serialize #endif #if USE_LINEAR import qualified Linear.Affine +import qualified Linear.Metric import qualified Linear.Vector #endif #if USE_VECTOR_SPACE @@ -156,6 +157,10 @@ instance Linear.Vector.Additive (Quantity d) where liftU2 = liftQ2 liftI2 f (Quantity x) (Quantity y) = Quantity $ f x y +instance Linear.Metric.Metric (Quantity DOne) where + dot (Quantity x) (Quantity y) = x P.* y + norm (Quantity x) = P.abs x + instance Linear.Affine.Affine (Quantity d) where type Diff (Quantity d) = Quantity d (.-.) = (Linear.Vector.^-^) From e2ecb40678f07fa94533999188a8af770409fb0a Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Thu, 31 Dec 2015 15:35:18 -0500 Subject: [PATCH 14/19] Deal with case of no flags and need to prepare new snapshot. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0f88e44d..e96bbad0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -71,7 +71,7 @@ install: echo "cabal build-cache MISS"; rm -rf $HOME/.cabsnap; mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin; - cabal install --only-dependencies --enable-tests --enable-benchmarks --flags $FLAGS; + cabal install --only-dependencies --enable-tests --enable-benchmarks --flags=$FLAGS; fi # snapshot package-db on cache miss From eb532761be4797d2f5767a3107852f1d70148334 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Fri, 22 Jan 2016 18:44:49 -0500 Subject: [PATCH 15/19] Removed the functor and linear flags. --- README.md | 7 +---- dimensional.cabal | 17 ----------- src/Numeric/Units/Dimensional/Functor.hs | 5 +--- src/Numeric/Units/Dimensional/Internal.hs | 35 ----------------------- 4 files changed, 2 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 2e16a55b..e284040a 100644 --- a/README.md +++ b/README.md @@ -68,16 +68,11 @@ main = do Package flags are available which enable us to provide instances for Quantity that are useful to interoperate with various popular packages without burdening all users with those dependencies or creating orphan instances. -To install with a `Functor` instance for quantities of all dimensions, instead of just -for dimensionless quantities, use: - -`cabal install dimensional -f functor` - To install with `ToJSON` and `FromJSON` instances for `Quantity`, use: `cabal install dimensional -f aeson` -Similarly the `binary`, `cereal`, `linear`, and `vector-space` flags enable appropriate +Similarly the `binary`, `cereal`, and `vector-space` flags enable appropriate instances for use with the packages of the same names. ## Contributing diff --git a/dimensional.cabal b/dimensional.cabal index 07608471..c89c3c2e 100644 --- a/dimensional.cabal +++ b/dimensional.cabal @@ -37,11 +37,6 @@ extra-source-files: README.md, examples/ReadmeExample.hs, examples/GM.lhs -flag functor - description: Provide a Functor instance for Quantity. - default: False - manual: True - flag aeson description: Provide instances for use with the aeson package. default: False @@ -57,11 +52,6 @@ flag cereal default: False manual: True -flag linear - description: Provide instances for use with the linear package. - default: False - manual: True - flag vector-space description: Provide instances for use with the vector-space package. default: False @@ -98,9 +88,6 @@ library other-modules: Numeric.Units.Dimensional.Internal, Numeric.Units.Dimensional.UnitNames.Internal - if flag(functor) - cpp-options: -DFUNCTOR - if flag(aeson) build-depends: aeson >= 0.10 && < 1 cpp-options: -DUSE_AESON @@ -113,10 +100,6 @@ library build-depends: cereal >= 0.5 && <1 cpp-options: -DUSE_CEREAL - if flag(linear) - build-depends: linear >= 1.19 && < 2 - cpp-options: -DUSE_LINEAR - if flag(vector-space) build-depends: vector-space >= 0.10 && < 1 cpp-options: -DUSE_VECTOR_SPACE diff --git a/src/Numeric/Units/Dimensional/Functor.hs b/src/Numeric/Units/Dimensional/Functor.hs index bde33dcd..3bead1cd 100644 --- a/src/Numeric/Units/Dimensional/Functor.hs +++ b/src/Numeric/Units/Dimensional/Functor.hs @@ -25,10 +25,8 @@ Note that, while this instance overlaps with that given for 'Dimensionless', it Note that this is an orphan instance. -} -module Numeric.Units.Dimensional.Functor {-# DEPRECATED "This orphan instance is being eliminated, along with the module packaging it, in favor of a package flag, functor, which creates it as a proper instance." #-} where +module Numeric.Units.Dimensional.Functor where --- If we already have this instance, we won't declare it again. -#if !(FUNCTOR || USE_LINEAR) import Numeric.Units.Dimensional -- | A 'Functor' instance for 'Dimensional'. @@ -40,4 +38,3 @@ import Numeric.Units.Dimensional -- Note that this is an orphan instance. instance {-# OVERLAPPING #-} (KnownVariant v) => Functor (Dimensional v d) where fmap = dmap -#endif diff --git a/src/Numeric/Units/Dimensional/Internal.hs b/src/Numeric/Units/Dimensional/Internal.hs index bc4c5919..97d0ba92 100644 --- a/src/Numeric/Units/Dimensional/Internal.hs +++ b/src/Numeric/Units/Dimensional/Internal.hs @@ -62,11 +62,6 @@ import qualified Data.Binary #if USE_CEREAL import qualified Data.Serialize #endif -#if USE_LINEAR -import qualified Linear.Affine -import qualified Linear.Metric -import qualified Linear.Vector -#endif #if USE_VECTOR_SPACE import qualified Data.AdditiveGroup import qualified Data.VectorSpace @@ -121,19 +116,8 @@ instance (Typeable m) => KnownVariant ('DUnit m) where injectValue _ _ = error "Shouldn't be reachable. Needed to name a quantity." dmap f (Unit n e x) = Unit n e (f x) -{- - -If the FUNCTOR flag is set or is required by another flag, we provide a Functor instance for all dimensional values. -Regardless, we provide a functor instance for dimensionless quantities. - --} -#if FUNCTOR || USE_LINEAR -instance (KnownVariant v) => Functor (Dimensional v d) where - fmap = dmap -#else instance Functor (Quantity DOne) where fmap = dmap -#endif #if USE_AESON deriving instance (Data.Aeson.ToJSON a) => Data.Aeson.ToJSON (Quantity d a) @@ -149,25 +133,6 @@ deriving instance (Data.Binary.Binary a) => Data.Binary.Binary (Quantity d a) deriving instance (Data.Serialize.Serialize a) => Data.Serialize.Serialize (Quantity d a) #endif -#if USE_LINEAR -instance Linear.Vector.Additive (Quantity d) where - zero = mempty - (^+^) = liftQ2 (P.+) - (^-^) = liftQ2 (P.-) - liftU2 = liftQ2 - liftI2 f (Quantity x) (Quantity y) = Quantity $ f x y - -instance Linear.Metric.Metric (Quantity DOne) where - dot (Quantity x) (Quantity y) = x P.* y - norm (Quantity x) = P.abs x - -instance Linear.Affine.Affine (Quantity d) where - type Diff (Quantity d) = Quantity d - (.-.) = (Linear.Vector.^-^) - (.+^) = (Linear.Vector.^+^) - (.-^) = (Linear.Vector.^-^) -#endif - #if USE_VECTOR_SPACE instance (Num a) => Data.AdditiveGroup.AdditiveGroup (Quantity d a) where zeroV = mempty From 92490864070ae0d494436f56e828d00c2b18ea1b Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 26 Jan 2016 10:11:00 -0500 Subject: [PATCH 16/19] Attempt to repair travis build with flags. --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 21e1ccf0..6c264e50 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,11 +20,11 @@ env: - ARGS="--resolver lts-2 --stack-yaml stack.lts2.yaml" - ARGS="--resolver lts-3" - ARGS="--resolver lts" -- ARGS="--resolver lts --flag dimensional:aeson" -- ARGS="--resolver lts --flag dimensional:binary" -- ARGS="--resolver lts --flag dimensional:cereal" -- ARGS="--resolver lts --flag dimensional:vector-space" -- ARGS="--resolver lts --flag dimensional:aeson --flag dimensional:binary --flag dimensional:cereal --flag dimensional:vector-space" +- ARGS="--resolver lts" FLAGS="--flag dimensional:aeson" +- ARGS="--resolver lts" FLAGS="--flag dimensional:binary" +- ARGS="--resolver lts" FLAGS="--flag dimensional:cereal" +- ARGS="--resolver lts" FLAGS="--flag dimensional:vector-space" +- ARGS="--resolver lts" FLAGS="--flag dimensional:aeson --flag dimensional:binary --flag dimensional:cereal --flag dimensional:vector-space" - ARGS="--resolver nightly" before_install: @@ -40,7 +40,7 @@ before_install: # This line does all of the work: build the library, # executables, and test suites, and runs the test suites. --no-terminal works # around some quirks in Travis's terminal implementation. -script: stack $ARGS --no-terminal test --haddock --bench +script: stack $ARGS $FLAGS --no-terminal test --haddock --bench # Caching so the next build will be fast too. cache: From 15e266ae9db0b4082ea418bac833fb5180ae3276 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 26 Jan 2016 10:19:47 -0500 Subject: [PATCH 17/19] Rearranged order of commands to appease stack/travis. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6c264e50..07ddefee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,7 @@ before_install: # This line does all of the work: build the library, # executables, and test suites, and runs the test suites. --no-terminal works # around some quirks in Travis's terminal implementation. -script: stack $ARGS $FLAGS --no-terminal test --haddock --bench +script: stack $ARGS --no-terminal test $FLAGS --haddock --bench # Caching so the next build will be fast too. cache: From 5537fd52b1762c477d90bfb068e56bd0422cc8d1 Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 26 Jan 2016 10:33:18 -0500 Subject: [PATCH 18/19] Relaxed version bounds for aeson. --- dimensional.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dimensional.cabal b/dimensional.cabal index c89c3c2e..65aa5aa2 100644 --- a/dimensional.cabal +++ b/dimensional.cabal @@ -89,7 +89,7 @@ library Numeric.Units.Dimensional.UnitNames.Internal if flag(aeson) - build-depends: aeson >= 0.10 && < 1 + build-depends: aeson >= 0.9 && < 1 cpp-options: -DUSE_AESON if flag(binary) From c5d84fc151616d410983f08a12b2c34901fa408c Mon Sep 17 00:00:00 2001 From: Douglas McClean Date: Tue, 26 Jan 2016 14:26:08 -0500 Subject: [PATCH 19/19] Changes for aeson 0.9 support. --- src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs | 4 ++-- src/Numeric/Units/Dimensional/Dynamic.hs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs b/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs index d6f3ba08..4eb1cf4b 100644 --- a/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs +++ b/src/Numeric/Units/Dimensional/Dimensions/TermLevel.hs @@ -44,6 +44,7 @@ import qualified Prelude as P -- Optional imports when certain package flags are enabled #if USE_AESON import qualified Data.Aeson +import qualified Data.Aeson.Types #endif #if USE_BINARY import qualified Data.Binary @@ -76,8 +77,7 @@ instance Monoid Dimension' where -- This instance only needs a body because an incorrect MINIMAL pragma in aeson-0.10 leads to -- a warning if you omit it. instance Data.Aeson.ToJSON Dimension' where - toJSON = Data.Aeson.genericToJSON Data.Aeson.defaultOptions - toEncoding = Data.Aeson.genericToEncoding Data.Aeson.defaultOptions + toJSON = Data.Aeson.genericToJSON Data.Aeson.Types.defaultOptions instance Data.Aeson.FromJSON Dimension' #endif diff --git a/src/Numeric/Units/Dimensional/Dynamic.hs b/src/Numeric/Units/Dimensional/Dynamic.hs index a15e4bfc..244bba5b 100644 --- a/src/Numeric/Units/Dimensional/Dynamic.hs +++ b/src/Numeric/Units/Dimensional/Dynamic.hs @@ -58,6 +58,7 @@ import qualified Numeric.Units.Dimensional.Dimensions.TermLevel as D -- Optional imports when certain package flags are enabled #if USE_AESON import qualified Data.Aeson +import qualified Data.Aeson.Types import qualified Data.Monoid #endif #if USE_BINARY @@ -137,7 +138,6 @@ instance Num a => Monoid (AnyQuantity a) where #if USE_AESON instance (Data.Aeson.ToJSON a) => Data.Aeson.ToJSON (AnyQuantity a) where toJSON (AnyQuantity d a) = Data.Aeson.object ["dimension" Data.Aeson..= d, "value" Data.Aeson..= a] - toEncoding (AnyQuantity d a) = Data.Aeson.pairs ("dimension" Data.Aeson..= d Data.Monoid.<> "value" Data.Aeson..= a) instance (Data.Aeson.FromJSON a) => Data.Aeson.FromJSON (AnyQuantity a) where parseJSON (Data.Aeson.Object v) = AnyQuantity P.<$> @@ -216,8 +216,7 @@ instance Num a => Monoid (DynQuantity a) where -- This instance only needs a body because an incorrect MINIMAL pragma in aeson-0.10 leads to -- a warning if you omit it. instance (Data.Aeson.ToJSON a) => Data.Aeson.ToJSON (DynQuantity a) where - toJSON = Data.Aeson.genericToJSON Data.Aeson.defaultOptions - toEncoding = Data.Aeson.genericToEncoding Data.Aeson.defaultOptions + toJSON = Data.Aeson.genericToJSON Data.Aeson.Types.defaultOptions instance (Data.Aeson.FromJSON a) => Data.Aeson.FromJSON (DynQuantity a) #endif