Reputation: 34021
I'd like to be able to serialize CommandRecord
into binary to be able to save it to a file. However my naive approach of just doing:
instance Binary CommandRecord
does not work due the below error*.
What approach can I use to achieve the above? Right now my thinking would be to work around this issue by, abandoning the idea of using the thyme
library and it's UTCTime
and instead use time
library and it's UTCTime
(which has a Binary instance already defined).
I have the follow data type:
data CommandRecord = CommandRecord {
command :: Text
, timedate :: UTCTime
, path :: Text
} deriving Generic
I have the following imports:
import Data.Thyme.Clock
import Data.Binary
import Data.Binary.Orphans
I'm using the following packages:
Error*:
/home/chris/Projects/Haskell/MoscoviumOrange/src/Main.hs:28:10-
29: error:
• No instance for (Binary UTCTime)
arising from a use of ‘binary-0.8.5.1:Data.Binary.Class
.$dmput’
There are instances for similar types:
instance Binary
time-1.8.0.2:Data.Time.Clock.Internal.UTCTim
e.UTCTime
-- Defined in ‘Data.Binary.Orphans’
• In the expression:
binary-0.8.5.1:Data.Binary.Class.$dmput @CommandRecord
In an equation for ‘put’:
put = binary-0.8.5.1:Data.Binary.Class.$dmput
@CommandRecord
In the instance declaration for ‘Binary CommandRecord’
|
28 | instance Binary CommandRecord
| ^^^^^^^^^^^^^^^^^^^^
/home/chris/Projects/Haskell/MoscoviumOrange/src/Main.hs:28:10-
29: error:
• No instance for (Binary UTCTime)
arising from a use of ‘binary-0.8.5.1:Data.Binary.Class
.$dmget’
There are instances for similar types:
instance Binary
time-1.8.0.2:Data.Time.Clock.Internal.UTCTim
e.UTCTime
-- Defined in ‘Data.Binary.Orphans’
• In the expression:
binary-0.8.5.1:Data.Binary.Class.$dmget @CommandRecord
In an equation for ‘get’:
get = binary-0.8.5.1:Data.Binary.Class.$dmget
@CommandRecord
In the instance declaration for ‘Binary CommandRecord’
|
28 | instance Binary CommandRecord
| ^^^^^^^^^^^^^^^^^^^^
Upvotes: 0
Views: 139
Reputation: 34021
Following with the 1. point from @leftaroundabout I ended up with the following module:
{-# OPTIONS -Wno-orphans #-}
module ThymeBinaryInstances where
import Data.Binary
import Data.Thyme.Internal.Micro
import Data.Thyme.Clock
instance Binary UTCTime
instance Binary NominalDiffTime
instance Binary Micro
Upvotes: 0
Reputation: 120741
Ah yes, the trivial-but-missing instance problem. What I would do:
instance Binary Thyme
as an orphan instance to yourmodule. Confirm that it works.#if !MIN_VERSION_thyme(0,3,6)
switch. The reason is, if a new version of thyme
appears that already includes the instance too, you don't want the duplicate instance to break your build.thyme<=0.3.5
in your .cabal
file, so a new version without the instance won't be tried. (This may seem to make the switch on the instance useless. The point is, you can edit the dependency bounds on Hackage after the fact, and should do so when a thyme
version with the instance appears.)thyme
maintainers that adds the instance. This should be uncontroversial, since thyme
indirectly depends on Binary
anyway.This is only advisable if what you're writing is an executable or small specialists library, though. If it's a library that lots of other projects might use, there's a risk of conflicting with somebody else's orphan instance. In that case, you should instead use a workaround until thyme
adds the instance:
data CommandRecord = CommandRecord {
command :: Text
, timedate :: UTCTime'
, path :: Text
} deriving Generic
newtype UTCTime' = UTCTime' {stdUTCThyme :: UTCTime}
instance Binary UTCTime' where
put = gput . from . stdUTCThyme
get = UTCTime' . to <$> gget
Upvotes: 1