... | ... | @@ -42,12 +42,30 @@ Foo.hs:7:10: |
|
|
|
|
|
then an easy way to fix this error is by defining an `Applicative` (and possibly a `Functor`) instance:
|
|
|
|
|
|
|
|
|
```
|
|
|
instanceFunctorFoowhere
|
|
|
instance Functor Foo where
|
|
|
fmap = liftM
|
|
|
-- or alternatively:-- fmap = m >>= pure . finstanceApplicativeFoowhere-- NB: DO NOT USE `pure = return`
|
|
|
pure ={- move the definition of `return` from the `Monad` instance here -}(<*>)= ap {- defined in Control.Monad -}-- or alternatively:-- f1 <*> f2 = f1 >>= \v1 -> f2 >>= (pure . v1)-- NB: DO NOT USE `(*>) = (>>)`(*>)={- move the definition of `>>` from the `Monad` instance here -}instanceMonadFoowhere
|
|
|
return = pure {- definition moved to `Applicative(pure)` -}(>>)=(*>){- definition moved to `Applicative((*>))` -}{- ...retain other previous definitions... -}
|
|
|
-- or alternatively:
|
|
|
-- fmap = m >>= pure . f
|
|
|
|
|
|
instance Applicative Foo where
|
|
|
-- NB: DO NOT USE `pure = return`
|
|
|
pure = {- move the definition of `return` from the `Monad` instance here -}
|
|
|
|
|
|
(<*>) = ap {- defined in Control.Monad -}
|
|
|
-- or alternatively:
|
|
|
-- f1 <*> f2 = f1 >>= \v1 -> f2 >>= (pure . v1)
|
|
|
|
|
|
-- NB: DO NOT USE `(*>) = (>>)`
|
|
|
(*>) = {- move the definition of `>>` from the `Monad` instance here -}
|
|
|
|
|
|
instance Monad Foo where
|
|
|
return = pure {- definition moved to `Applicative(pure)` -}
|
|
|
|
|
|
(>>) = (*>) {- definition moved to `Applicative((*>))` -}
|
|
|
|
|
|
{- ...retain other previous definitions... -}
|
|
|
```
|
|
|
|
|
|
|
... | ... | @@ -65,28 +83,40 @@ For more details see [ AMP Proposal: Future-proofing current code](https://www.h |
|
|
#### GHC says `No instance for (Alternative ...)`
|
|
|
|
|
|
|
|
|
|
|
|
A side-effect of the AMP is that `Alternative` became a super-class of `MonadPlus`. The easy remedy:
|
|
|
|
|
|
|
|
|
```
|
|
|
instanceAlternativeFoowhere(<|>)= mplus
|
|
|
instance Alternative Foo where
|
|
|
(<|>) = mplus
|
|
|
empty = mzero
|
|
|
```
|
|
|
|
|
|
|
|
|
If pre-AMP compatibility is not a requirement, it's better to define `MonadPlus` in terms of `Alternative` as this corresponds to the superclass relationship and allows to omit the method definitions in `MonadPlus`, i.e.
|
|
|
|
|
|
|
|
|
```
|
|
|
instanceAlternativeFoowhere
|
|
|
empty ={- move definition of `mzero` here -}(<|>)={- move definition of `mplus` here -}instanceMonadPlusFoo-- NB: starting with `base-4.8`: no need to override methods here!
|
|
|
instance Alternative Foo where
|
|
|
empty = {- move definition of `mzero` here -}
|
|
|
(<|>) = {- move definition of `mplus` here -}
|
|
|
|
|
|
instance MonadPlus Foo -- NB: starting with `base-4.8`: no need to override methods here!
|
|
|
```
|
|
|
|
|
|
#### GHC says `No instance for (Foldable ...) arising from the use of...`
|
|
|
|
|
|
|
|
|
|
|
|
Some functions in the Prelude were generalised to `Foldable`s in the implementation of the FTP. This can lead to type-inference problems for code making use of `-XOverloadedStrings`, in which code like e.g.
|
|
|
|
|
|
|
|
|
```
|
|
|
{-# LANGUAGE OverloadedStrings #-}main::IO()main= print ('I'`elem`"team")
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
|
main :: IO ()
|
|
|
main = print ('I' `elem` "team")
|
|
|
```
|
|
|
|
|
|
|
... | ... | @@ -120,10 +150,16 @@ This can be fixed by helping GHC's type-inference to pin down `"team"` to `[Char |
|
|
#### GHC says `The import of ... is redundant`
|
|
|
|
|
|
|
|
|
|
|
|
With `base-4.8`, the `Prelude` re-exports a few more entities from modules such as `Data.Monoid` and `Control.Applicative`. For example, the following module
|
|
|
|
|
|
|
|
|
```
|
|
|
moduleFoo(Int,Word,Monoid(..))whereimportData.MonoidimportData.Word-- import Prelude
|
|
|
module Foo (Int, Word, Monoid(..)) where
|
|
|
|
|
|
import Data.Monoid
|
|
|
import Data.Word
|
|
|
-- import Prelude
|
|
|
```
|
|
|
|
|
|
|
... | ... | @@ -148,27 +184,39 @@ This `import Prelude`-trick, however, doesn't work when explicit import lists ar |
|
|
One obvious way to silence such warnings is use `-XCPP`. However, there's also a less-known trick/hack to moving the implicit `import Prelude` into an explicit one after all `base`-imports. In the code example above just de-comment the `-- import Prelude` line.
|
|
|
|
|
|
|
|
|
|
|
|
A more robust way (that works when the trick above doesn't work) to convince GHC without `-XCPP` to suppress redundancy-warnings is by referencing a module-prefixed entity form the respective module at least once. In the example below, `pure` is referenced just once via `A.pure`, thereby marking the `import` essential:
|
|
|
|
|
|
|
|
|
```
|
|
|
importControl.Applicativeas A (Applicative(..))dataMaybe' a =Nothing'|Just' a
|
|
|
import Control.Applicative as A (Applicative(..))
|
|
|
|
|
|
instanceFunctorMaybe'where
|
|
|
fmap f (Just' v)=Just'(f v)
|
|
|
fmap _Nothing'=Nothing'instanceApplicativeMaybe'where
|
|
|
pure =Just'
|
|
|
f1 <*> f2 = f1 >>=\v1 -> f2 >>=(pure . v1)instanceMonadMaybe'whereNothing'>>=_=Nothing'Just' x >>= f = f x
|
|
|
data Maybe' a = Nothing' | Just' a
|
|
|
|
|
|
return =A.pure -- NB: This definition is redundant since GHC 7.10/base-4.8
|
|
|
instance Functor Maybe' where
|
|
|
fmap f (Just' v) = Just' (f v)
|
|
|
fmap _ Nothing' = Nothing'
|
|
|
|
|
|
instance Applicative Maybe' where
|
|
|
pure = Just'
|
|
|
f1 <*> f2 = f1 >>= \v1 -> f2 >>= (pure . v1)
|
|
|
|
|
|
instance Monad Maybe' where
|
|
|
Nothing' >>= _ = Nothing'
|
|
|
Just' x >>= f = f x
|
|
|
|
|
|
return = A.pure -- NB: This definition is redundant since GHC 7.10/base-4.8
|
|
|
```
|
|
|
|
|
|
### `deepseq-1.4.0.0` (& `deepseq-1.4.1.0`)
|
|
|
|
|
|
|
|
|
|
|
|
The default method implementation has been changed, so instances defined via
|
|
|
|
|
|
|
|
|
```
|
|
|
instanceNFDataFoo
|
|
|
instance NFData Foo
|
|
|
```
|
|
|
|
|
|
|
... | ... | @@ -185,8 +233,9 @@ Foo.hs:5:10: |
|
|
|
|
|
The easiest way make code work again with `deepseq-1.4.0.0` which was relying on the pre-1.4 default method implementation of `rnf` is to explicitly define `rnf` like so
|
|
|
|
|
|
|
|
|
```
|
|
|
instanceNFDataFoowhere rnf x = seq x ()
|
|
|
instance NFData Foo where rnf x = seq x ()
|
|
|
```
|
|
|
|
|
|
|
... | ... | @@ -201,17 +250,25 @@ For more details (and how to use the new facilities) see Haddock documentation o |
|
|
The internal representation for `Integer`s has changed. Code only referencing the `S#` constructor should not be affected. The `J#` constructor however has been replaced by two new `Jp#` and `Jn#` constructors (see below).
|
|
|
|
|
|
|
|
|
|
|
|
Old representation:
|
|
|
|
|
|
|
|
|
```
|
|
|
dataInteger=S#Int#-- ^ \"small\" integers fitting into an 'Int#'|J#Int#ByteArray#-- ^ \"big\" integers (legal to be used to represent 'Int#'-range)
|
|
|
data Integer
|
|
|
= S# Int# -- ^ \"small\" integers fitting into an 'Int#'
|
|
|
| J# Int# ByteArray# -- ^ \"big\" integers (legal to be used to represent 'Int#'-range)
|
|
|
```
|
|
|
|
|
|
|
|
|
New representation:
|
|
|
|
|
|
|
|
|
```
|
|
|
dataInteger=S#Int#-- ^ iff value in @[minBound::'Int', maxBound::'Int']@ range|Jp#!BigNat-- ^ iff value in @]maxBound::'Int', +inf[@ range|Jn#!BigNat-- ^ iff value in @]-inf, minBound::'Int'[@ range
|
|
|
data Integer
|
|
|
= S# Int# -- ^ iff value in @[minBound::'Int', maxBound::'Int']@ range
|
|
|
| Jp# !BigNat -- ^ iff value in @]maxBound::'Int', +inf[@ range
|
|
|
| Jn# !BigNat -- ^ iff value in @]-inf, minBound::'Int'[@ range
|
|
|
```
|
|
|
|
|
|
|
... | ... | @@ -240,10 +297,13 @@ See [ https://github.com/bos/aeson/commit/730a8c42b75f38e241da39933b03735a7c9055 |
|
|
### `array-0.5.1.0`
|
|
|
|
|
|
|
|
|
|
|
|
In 0.5.0.0, one could derive Data.Array.Unboxed instances for newtype Int's, Word64's etc.:
|
|
|
|
|
|
|
|
|
```
|
|
|
newtypeN=MkNWord64deriving(IArrayUArray)
|
|
|
newtype N = MkN Word64
|
|
|
deriving (IArray UArray)
|
|
|
```
|
|
|
|
|
|
|
... | ... | |