Closed RyanGlScott closed 5 years ago
One option is to add instances for old boot library Monad(Fail)
s into fail
package. That’s some work, not sure if GHC-7.10 is worth it. Neither whether Herbert would agree with that.
I’m ok for dropping old binary
support. fail
plan can be implemented later, if there’s need for it.
On 27 Apr 2019, at 16.26, Ryan Scott notifications@github.com wrote:
bytes fails to build with GHC 8.8.1-alpha1:
All of these errors occur within a MonadGet constraint, so one tempting solution to this problem is to simply make MonadFail a superclass of MonadGet:
diff --git a/bytes.cabal b/bytes.cabal index 401777b..540c928 100644 --- a/bytes.cabal +++ b/bytes.cabal @@ -74,7 +74,8 @@ library build-depends: ghc-prim
if impl(ghc < 8.0)
- build-depends: semigroups >= 0.5 && < 1
- build-depends: fail == 4.9.*,
semigroups >= 0.5 && < 1
exposed-modules: Data.Bytes.Get diff --git a/src/Data/Bytes/Get.hs b/src/Data/Bytes/Get.hs index 6ab1a04..fd5e26b 100644 --- a/src/Data/Bytes/Get.hs +++ b/src/Data/Bytes/Get.hs @@ -28,6 +28,7 @@ module Data.Bytes.Get
if __GLASGOW_HASKELL__ < 710
import Control.Applicative
endif
+import qualified Control.Monad.Fail as Fail import Control.Monad.Reader import Control.Monad.Trans.Except as Except import Control.Monad.RWS.Lazy as Lazy @@ -43,7 +44,7 @@ import Data.Int import qualified Data.Serialize.Get as S import Data.Word
-class (Integral (Remaining m), Monad m, Applicative m) => MonadGet m where +class (Integral (Remaining m), Fail.MonadFail m, Applicative m) => MonadGet m where -- | An 'Integral' number type used for unchecked skips and counting. type Remaining m :: * This makes bytes build on recent GHCs. For older (pre-8.0) GHCs, however, this presents a problem. Here's what happens if you build with GHC 7.10.3, for instance:
[4 of 5] Compiling Data.Bytes.Get ( src/Data/Bytes/Get.hs, /home/rgscott/Documents/Hacking/Haskell/staging/bytes/dist-newstyle/build/x86_64-linux/ghc-7.10.3/bytes-0.15.5/build/Data/Bytes/Get.o )
src/Data/Bytes/Get.hs:202:10: No instance for (Fail.MonadFail B.Get) arising from the superclasses of an instance declaration In the instance declaration for ‘MonadGet B.Get’ Eek! Get from the binary package has only been an instance of MonadFail since 0.8.2.0, which is more recent than the version that is shipped with GHC 7.10.3.
One alternative woud be to switch all uses of fail with error. But this feels a bit wrong, since most parser data types have dedicated fail implementations that do something besides throw an exception.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.
I think adding new instances to the fail
package is a no-go. I've proposed this idea to @hvr once and he (somewhat understandably) wasn't enthusiastic about maintaining out the necessary CPP to make this work. This is why I ended up backporting MonadFail
instances for monad transformer types separately in transformers-compat
. As @hvr predicted, the CPP required ended up being a huge mess.
I suppose we could guard the MonadGet Get
instance behind a Cabal
flag, much like the parsers
package does. Of course, this would necessarily require dropping support for certain pre–GHC 8.0 build plans. I wonder how many people would actually be affected by this?
Seems like it's worth having a survey how many GHC releases do people want the ecosystem to support ? Supporting GHCs older than 8.0 is getting quite painful.
To be clear, it would be quite easy to continue supporting the main skeleton of bytes
on old GHCs. The real question is how far back we wish to provide instances for data types in the binary
package.
One thing worth noting is that conditionally exposing the MonadGet Data.Binary.Get
instance would affect some of bytes
' dependencies. I've confirmed that the bound
and linear
libraries both rely on the existence of a MonadGet Data.Binary.Get
instance in order to compile, and it's possible that there are other, non-Kmett libraries that do the same.
I could add MonadFail Get to binary-orphans
. It’s on the lightest dependency, but if it doesn’t form cycle it would work.
Users of old GHC would have to pay, but they would get new bytes
:)
On 3 May 2019, at 15.52, Ryan Scott notifications@github.com wrote:
One thing worth noting is that conditionally exposing the MonadGet Data.Binary.Get instance would affect some of bytes' dependencies. I've confirmed that the bound and linear libraries both rely on the existence of a MonadGet Data.Binary.Get instance in order to compile, and it's possible that there are other, non-Kmett libraries that do the same.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
If we do go down the orphan-instance package route, it almost feels like this instance deserves its own library. binary-orphans
, AFAICT, exists to provide orphan Binary
instances for data types which do not otherwise have them, whereas we wish to simply backport an existing instance from the binary
package to make it available on old versions of binary
. That would also have the added bonus of not having to incur dependencies on huge packages like aeson
when building with old versions of GHC.
Unfortunately, the name binary-orphans
has already been taken, so it's unclear to me what to call this hypothetical compatibility package.
binary-fail :)
Sent from my iPhone
On 3 May 2019, at 16.07, Ryan Scott notifications@github.com wrote:
If we do go down the orphan-instance package route, it almost feels like this instance deserves its own library. binary-orphans, AFAICT, exists to provide orphan Binary instances for data types which do not otherwise have them, whereas we wish to simply backport an existing instance from the binary package to make it available on old versions of binary. That would also have the added bonus of not having to incur dependencies on huge packages like aeson when building with old versions of GHC.
Unfortunately, the name binary-orphans has already been taken, so it's unclear to me what to call this hypothetical compatibility package.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
Resolved in #47.
I'm probably not saying anything new to anyone here, but, for the record, I'm okay with pulling the plug on GHC < 8.0 or on comparably old binary
versions for new releases of bytes
. Legacy code can be supported by legacy code. What is required is that some version of bytes
can satisfy the dependency, when existing code depends on bytes
, not that the current version builds back to the stone age.
That policy might allow us a more sane upgrade and maintenance path, at the cost of occasionally having to backport the odd mission critical patch here or there.
bytes
fails to build with GHC 8.8.1-alpha1:All of these errors occur within a
MonadGet
constraint, so one tempting solution to this problem is to simply makeMonadFail
a superclass ofMonadGet
:This makes
bytes
build on recent GHCs. For older (pre-8.0) GHCs, however, this presents a problem. Here's what happens if you build with GHC 7.10.3, for instance:Eek!
Get
from thebinary
package has only been an instance ofMonadFail
since0.8.2.0
, which is more recent than the version that is shipped with GHC 7.10.3.One alternative woud be to switch all uses of
fail
witherror
. But this feels a bit wrong, since most parser data types have dedicatedfail
implementations that do something besides throw an exception.