Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Generics.Diff
Contents
Description
Generic detailed comparisons, without boilerplate.
The simplest way in Haskell that we can use to compare two values of the same type is using Eq
.
The (==)
operator gives us a simple Bool
ean response: True
if the values are equal, or False
otherwise.
Slightly more informative is Ord
: the compare
function (or operators (<=)
, (>)
etc) tells
us, if two values are different, which one can be considered as "less than" or "more than" the other.
One situation in which these might not be enough is testing. Say you have a pair of (de)serialisation functions (which we'll imagine are total, for simplicity), and which we expect to be inverses:
serialise :: (Serialise a) => a -> String deserialise :: (Serialise a) => String -> a
Let's imagine we have some (Hspec) tests, e.g.:
unitTest :: (Serialise a) => a -> Spec unitTest value = let serialised = serialise value deserailised = deserialise serialised in it "Serialisation should satisfy the round-trip property" $ deserialised `shouldBe` value
What happens if the test fails? If we're dealing with a simple type like Int
, the error will be very
easy to debug:
1) Serialisation should satisfy the round-trip property expected: 2 but got: 1
But what if our type is much more complicated, with lots of constructors, fields, nesting... Especially if the type has a derived show instance, the output can be very dense, littered with parentheses, and overall very difficult to play "spot the difference" with.
That's where this library comes in handy. Using the Diff
typeclass, we can identify precisely
where two values differ. A "top-level" diff will tell you at which constructor and which field the values
are different; if the types of those fields also have useful Diff
instances, we can recurse into them to
pinpoint the error even more accurately. Even better, we can derive our Diff
instances completely
automatically as long as our types have instances for Generic
(and
HasDatatypeInfo
) from generics-sop.
In fact, we use the types NP
and NS
extensively to define the types we
use for representing diffs.
Understanding
To aid understanding (both for this library and for generics-sop
), I think it helps to think of an ADT
as a grid:
data MyType = Con1 Char (Either Int String) | Con2 [Bool]
This corresponds to a grid with one row per constructor, one column per field:
Constructor | Fields | |
---|---|---|
Con1 | Char | Either Int String |
Con2 | [Bool] | N / A |
A value of type MyType
can be thought of as being one row of the grid, with one value for each
column in the row.
Now, if we have two values of type MyType
, there's too main ways they can differ. If they inhabit
different rows of the grid, they're clearly not equal, and all we can say is "this one uses this
constructor, that one uses that constructor" (see WrongConstructor
). In other words we just report the
names of the two rows.
If they inhabit the same row of the grid, we have to go column by column, comparing each pair of values (we'll
get to how we compare them in a second).
If they're all pairwise equal, we can conclude the two values are Equal
; if one pair fails the comparison
test, we stop checking and say "the types differ at this constructor, in this field" (see FieldMismatch
).
Effectively, we point to a single cell of the grid and say "that's where the inequality is".
You might note that this process is very similar to how a stock-derived Eq
instance works. All we've added
so far is an extra dimension to the output, detailing not just that two values differ, but where in the grid
they differ. Where things get interesting is how we do the pairwise comparison between fields. If the
comparison test is (==)
, then it's as above: we find out that two values are either equal, or not equal; and
if they're not equal, we find out at which field that inequality happens. However, as in MyType
above, types
often refer to other types! Either Int String
also has its own grid:
-- excuse the pseudo-Haskell type Either Int String = Left Int | Right String
Similar to above, we have:
Constructor | Fields |
---|---|
Left | Int |
Right | String |
In fact, if we squint a bit, this grid actually exists inside the cell of the MyType
grid:
Con1 | Char | Left | Int |
Right | String | ||
Con2 | [Bool] | N / A |
This gives us an extra level of granularity: when we get to the pair of Either Int String
fields, rather than
just delegating to Eq
, we can go through the same procedure as above. Then instead of "the two values differ at the
Either Int String
field of the Con1
constructor", we can say "the two values differ at the Either Int String
field of the Con1
constructor, and those two field differs because one uses the Left
constructor and the other
uses the Right
constructor"! And of course, once we have one step of recursion, we have as many as we want...
Implementing instances
The Diff
class encapsulates the above behaviour with diff
. It's very strongly recommended that you don't
implement diff
yourself, but use the default implementation using Generic
, which is just gdiff
.
In the rare case you might want to implement diff
yourself, there are two other functions you might want to use.
eqDiff
simply delegates the entire process to(==)
, and will only ever giveEqual
orTopLevelNotEqual
. This is no more useful thanEq
, and should only be used for primitive types (e.g. all numeric types likeChar
andInt
) useeqDiff
, since they don't really have ADTs or recursion. This is the only implementation that doesn't require an instance ofGeneric
.gdiffTopLevel
does the above process, but without recursion. In other words each pair of fields is compared using(==)
. This is definitely better thanEq
, by one "level". One situation when this might be useful is when your type refers to types from other libraries, and you want to avoid orphanDiff
instances for those types. Another is when the types of the fields are "small" enough that we don't care about recursing into them. For example:
data HttpVersion = Http1 | Http2 deriving (Eq) data Request = Request { host :: String , port :: Int -- there's no instance ofDiff
forMap
, so just compare for equality using(==)
, parameters :: Map String String --Diff
doesn't really add anything overEq
for enum types, soEq
is fine , httpVersion :: HttpVersion } deriving stock (GHC.Generics.Generic) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) instanceDiff
Request wherediff
=gdiffTopLevel
For completeness, we also provide one more implementation function: gdiffWith
lets you provide a set of
Differ
s (comparison functions) to use for each pair of fields (one per cell of the grid).
I'm not sure in what situation you'd want this, but there you go.
Synopsis
- class Diff a where
- diff :: a -> a -> DiffResult a
- diffList :: [a] -> [a] -> DiffResult [a]
- gdiff :: forall a. (Generic a, HasDatatypeInfo a, All2 Diff (Code a)) => a -> a -> DiffResult a
- gdiffTopLevel :: forall a. (Generic a, HasDatatypeInfo a, All2 Eq (Code a)) => a -> a -> DiffResult a
- gdiffWith :: forall a. (Generic a, HasDatatypeInfo a) => POP Differ (Code a) -> a -> a -> DiffResult a
- eqDiff :: Eq a => a -> a -> DiffResult a
- data DiffResult a
- data DiffError a where
- TopLevelNotEqual :: DiffError a
- Nested :: DiffErrorNested (Code a) -> DiffError a
- DiffList :: ListDiffError a -> DiffError [a]
- DiffNonEmpty :: ListDiffError a -> DiffError (NonEmpty a)
- data DiffErrorNested xss
- = WrongConstructor (NS ConstructorInfo xss) (NS ConstructorInfo xss)
- | FieldMismatch (DiffAtField xss)
- data ListDiffError a
- = DiffAtIndex Int (DiffError a)
- | WrongLengths Int Int
- newtype DiffAtField xss = DiffAtField (NS (ConstructorInfo :*: NS DiffError) xss)
- data (f :*: g) a = (f a) :*: (g a)
- newtype Differ x = Differ (x -> x -> DiffResult x)
Class
A type with an instance of Diff
permits a more nuanced comparison than Eq
or Ord
.
If two values are not equal, diff
will tell you exactly where they differ ("in this contructor,
at that field"). The granularity of the pinpointing of the difference (how many "levels" of Diff
we can "descend" through) depends on the implementation of the instance.
For user-defined types, it's strongly recommended you derive your Diff
instance using Generic
from
generics-sop
. If those types refer to other types, those will need Diff
instances too. For example:
{-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveAnyClass #-} import qualified GHC.Generics as G import qualified Generics.SOP as SOP data BinOp = Plus | Minus deriving stock (Show, G.Generic) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo, Diff) data Expr = Atom Int | Bin {left :: Expr, op :: BinOp, right :: Expr} deriving stock (Show, G.Generic) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo, Diff)
Now that we have our instances, we can diff
values to find out exactly where they differ:
-- If two values are equal,diff
should always returnEqual
. ghci> diff Plus Plus Equal ghci> diff Plus Minus Error (Nested (WrongConstructor (Z (Constructor "Plus")) (S (Z (Constructor "Minus"))))) ghci> diff (Atom 1) (Atom 2) Error (Nested (FieldMismatch (AtLoc (Z (Constructor "Atom" :*: Z (Nested TopLevelNotEqual)))))) ghci> diff (Bin (Atom 1) Plus (Atom 1)) (Atom 2) Error (Nested (WrongConstructor (S (Z (Constructor "Bin"))) (Z (Constructor "Atom")))) ghci> diff (Bin (Atom 1) Plus (Atom 1)) (Bin (Atom 1) Minus (Atom 1)) Error (Nested (FieldMismatch (AtLoc (S (Z (Constructor "Bin" :*: S (Z (Nested (WrongConstructor (Z (Constructor "Plus")) (S (Z (Constructor "Minus")))))))))))) ghci> diff (Bin (Atom 1) Plus (Atom 1)) (Bin (Atom 1) Plus (Atom 2)) Error (Nested (FieldMismatch (DiffAtField (S (Z (Record "Bin" (FieldInfo "left" :* FieldInfo "op" :* FieldInfo "right" :* Nil) :*: S (S (Z (Nested (FieldMismatch (DiffAtField (Z (Constructor "Atom" :*: Z TopLevelNotEqual)))))))))))))
Of course, these are just as difficult to understand as derived Show
instances, or more so. Fortunately we can
use the functions in Generics.Diff.Render to get a nice, intuitive representation of the diffs:
ghci> printDiffResult $ diff Plus Plus Equal ghci> printDiffResult $ diff Plus Minus Wrong constructor Constructor of left value: Plus Constructor of right value: Minus ghci> printDiffResult $ diff (Atom 1) (Atom 2) Both values use constructor Atom but fields don't match In field 0 (0-indexed): Not equal ghci> printDiffResult $ diff (Bin (Atom 1) Plus (Atom 1)) (Atom 2) Wrong constructor Constructor of left value: Bin Constructor of right value: Atom ghci> printDiffResult $ diff (Bin (Atom 1) Plus (Atom 1)) (Bin (Atom 1) Minus (Atom 1)) Both values use constructor Bin but fields don't match In field op: Wrong constructor Constructor of left value: Plus Constructor of right value: Minus ghci> printDiffResult $ diff (Bin (Atom 1) Plus (Atom 1)) (Bin (Atom 1) Plus (Atom 2)) Both values use constructor Bin but fields don't match In field right: Both values use constructor Atom but fields don't match In field 0 (0-indexed): Not equal
Laws
For type a
with instance Diff a
, and values x, y :: a
, the following should hold:
x == y <=> x `diff` y == Equal
Minimal complete definition
Nothing
Methods
diff :: a -> a -> DiffResult a Source #
Detailed comparison of two values. It is strongly recommended to only use the
default implementation, or one of eqDiff
or gdiffTopLevel
.
default diff :: (Generic a, HasDatatypeInfo a, All2 Diff (Code a)) => a -> a -> DiffResult a Source #
diffList :: [a] -> [a] -> DiffResult [a] Source #
Instances
Diff ByteArray Source # | |
Defined in Generics.Diff.Instances | |
Diff DataRep Source # | |
Defined in Generics.Diff.Instances | |
Diff E0 Source # | |
Defined in Generics.Diff.Instances | |
Diff E1 Source # | |
Defined in Generics.Diff.Instances | |
Diff E12 Source # | |
Defined in Generics.Diff.Instances | |
Diff E2 Source # | |
Defined in Generics.Diff.Instances | |
Diff E3 Source # | |
Defined in Generics.Diff.Instances | |
Diff E6 Source # | |
Defined in Generics.Diff.Instances | |
Diff E9 Source # | |
Defined in Generics.Diff.Instances | |
Diff All Source # | |
Defined in Generics.Diff.Instances | |
Diff Any Source # | |
Defined in Generics.Diff.Instances | |
Diff TypeRep Source # | |
Defined in Generics.Diff.Instances | |
Diff Unique Source # | |
Defined in Generics.Diff.Instances | |
Diff Version Source # | |
Defined in Generics.Diff.Instances | |
Diff Errno Source # | |
Defined in Generics.Diff.Instances | |
Diff CBool Source # | |
Defined in Generics.Diff.Instances | |
Diff CChar Source # | |
Defined in Generics.Diff.Instances | |
Diff CClock Source # | |
Defined in Generics.Diff.Instances | |
Diff CDouble Source # | |
Defined in Generics.Diff.Instances | |
Diff CFloat Source # | |
Defined in Generics.Diff.Instances | |
Diff CInt Source # | |
Defined in Generics.Diff.Instances | |
Diff CIntMax Source # | |
Defined in Generics.Diff.Instances | |
Diff CIntPtr Source # | |
Defined in Generics.Diff.Instances | |
Diff CLLong Source # | |
Defined in Generics.Diff.Instances | |
Diff CLong Source # | |
Defined in Generics.Diff.Instances | |
Diff CPtrdiff Source # | |
Defined in Generics.Diff.Instances | |
Diff CSChar Source # | |
Defined in Generics.Diff.Instances | |
Diff CSUSeconds Source # | |
Defined in Generics.Diff.Instances Methods diff :: CSUSeconds -> CSUSeconds -> DiffResult CSUSeconds Source # diffList :: [CSUSeconds] -> [CSUSeconds] -> DiffResult [CSUSeconds] Source # | |
Diff CShort Source # | |
Defined in Generics.Diff.Instances | |
Diff CSigAtomic Source # | |
Defined in Generics.Diff.Instances Methods diff :: CSigAtomic -> CSigAtomic -> DiffResult CSigAtomic Source # diffList :: [CSigAtomic] -> [CSigAtomic] -> DiffResult [CSigAtomic] Source # | |
Diff CSize Source # | |
Defined in Generics.Diff.Instances | |
Diff CTime Source # | |
Defined in Generics.Diff.Instances | |
Diff CUChar Source # | |
Defined in Generics.Diff.Instances | |
Diff CUInt Source # | |
Defined in Generics.Diff.Instances | |
Diff CUIntMax Source # | |
Defined in Generics.Diff.Instances | |
Diff CUIntPtr Source # | |
Defined in Generics.Diff.Instances | |
Diff CULLong Source # | |
Defined in Generics.Diff.Instances | |
Diff CULong Source # | |
Defined in Generics.Diff.Instances | |
Diff CUSeconds Source # | |
Defined in Generics.Diff.Instances | |
Diff CUShort Source # | |
Defined in Generics.Diff.Instances | |
Diff CWchar Source # | |
Defined in Generics.Diff.Instances | |
Diff IntPtr Source # | |
Defined in Generics.Diff.Instances | |
Diff WordPtr Source # | |
Defined in Generics.Diff.Instances | |
Diff Void Source # | |
Defined in Generics.Diff.Instances | |
Diff ByteOrder Source # | |
Defined in Generics.Diff.Instances | |
Diff BlockReason Source # | |
Defined in Generics.Diff.Instances Methods diff :: BlockReason -> BlockReason -> DiffResult BlockReason Source # diffList :: [BlockReason] -> [BlockReason] -> DiffResult [BlockReason] Source # | |
Diff ThreadId Source # | |
Defined in Generics.Diff.Instances | |
Diff ThreadStatus Source # | |
Defined in Generics.Diff.Instances Methods diff :: ThreadStatus -> ThreadStatus -> DiffResult ThreadStatus Source # diffList :: [ThreadStatus] -> [ThreadStatus] -> DiffResult [ThreadStatus] Source # | |
Diff Event Source # | |
Defined in Generics.Diff.Instances | |
Diff Lifetime Source # | |
Defined in Generics.Diff.Instances | |
Diff FdKey Source # | |
Defined in Generics.Diff.Instances | |
Diff TimeoutKey Source # | |
Defined in Generics.Diff.Instances Methods diff :: TimeoutKey -> TimeoutKey -> DiffResult TimeoutKey Source # diffList :: [TimeoutKey] -> [TimeoutKey] -> DiffResult [TimeoutKey] Source # | |
Diff ErrorCall Source # | |
Defined in Generics.Diff.Instances | |
Diff ArithException Source # | |
Defined in Generics.Diff.Instances Methods diff :: ArithException -> ArithException -> DiffResult ArithException Source # diffList :: [ArithException] -> [ArithException] -> DiffResult [ArithException] Source # | |
Diff Fingerprint Source # | |
Defined in Generics.Diff.Instances Methods diff :: Fingerprint -> Fingerprint -> DiffResult Fingerprint Source # diffList :: [Fingerprint] -> [Fingerprint] -> DiffResult [Fingerprint] Source # | |
Diff Associativity Source # | |
Defined in Generics.Diff.Instances Methods diff :: Associativity -> Associativity -> DiffResult Associativity Source # diffList :: [Associativity] -> [Associativity] -> DiffResult [Associativity] Source # | |
Diff DecidedStrictness Source # | |
Defined in Generics.Diff.Instances Methods diff :: DecidedStrictness -> DecidedStrictness -> DiffResult DecidedStrictness Source # diffList :: [DecidedStrictness] -> [DecidedStrictness] -> DiffResult [DecidedStrictness] Source # | |
Diff Fixity Source # | |
Defined in Generics.Diff.Instances | |
Diff MaskingState Source # | |
Defined in Generics.Diff.Instances Methods diff :: MaskingState -> MaskingState -> DiffResult MaskingState Source # diffList :: [MaskingState] -> [MaskingState] -> DiffResult [MaskingState] Source # | |
Diff BufferState Source # | |
Defined in Generics.Diff.Instances Methods diff :: BufferState -> BufferState -> DiffResult BufferState Source # diffList :: [BufferState] -> [BufferState] -> DiffResult [BufferState] Source # | |
Diff IODeviceType Source # | |
Defined in Generics.Diff.Instances Methods diff :: IODeviceType -> IODeviceType -> DiffResult IODeviceType Source # diffList :: [IODeviceType] -> [IODeviceType] -> DiffResult [IODeviceType] Source # | |
Diff SeekMode Source # | |
Defined in Generics.Diff.Instances | |
Diff ArrayException Source # | |
Defined in Generics.Diff.Instances Methods diff :: ArrayException -> ArrayException -> DiffResult ArrayException Source # diffList :: [ArrayException] -> [ArrayException] -> DiffResult [ArrayException] Source # | |
Diff AsyncException Source # | |
Defined in Generics.Diff.Instances Methods diff :: AsyncException -> AsyncException -> DiffResult AsyncException Source # diffList :: [AsyncException] -> [AsyncException] -> DiffResult [AsyncException] Source # | |
Diff ExitCode Source # | |
Defined in Generics.Diff.Instances | |
Diff IOErrorType Source # | |
Defined in Generics.Diff.Instances Methods diff :: IOErrorType -> IOErrorType -> DiffResult IOErrorType Source # diffList :: [IOErrorType] -> [IOErrorType] -> DiffResult [IOErrorType] Source # | |
Diff IOException Source # | |
Defined in Generics.Diff.Instances Methods diff :: IOException -> IOException -> DiffResult IOException Source # diffList :: [IOException] -> [IOException] -> DiffResult [IOException] Source # | |
Diff HandlePosn Source # | |
Defined in Generics.Diff.Instances Methods diff :: HandlePosn -> HandlePosn -> DiffResult HandlePosn Source # diffList :: [HandlePosn] -> [HandlePosn] -> DiffResult [HandlePosn] Source # | |
Diff BufferMode Source # | |
Defined in Generics.Diff.Instances Methods diff :: BufferMode -> BufferMode -> DiffResult BufferMode Source # diffList :: [BufferMode] -> [BufferMode] -> DiffResult [BufferMode] Source # | |
Diff Handle Source # | |
Defined in Generics.Diff.Instances | |
Diff Newline Source # | |
Defined in Generics.Diff.Instances | |
Diff NewlineMode Source # | |
Defined in Generics.Diff.Instances Methods diff :: NewlineMode -> NewlineMode -> DiffResult NewlineMode Source # diffList :: [NewlineMode] -> [NewlineMode] -> DiffResult [NewlineMode] Source # | |
Diff IOMode Source # | |
Defined in Generics.Diff.Instances | |
Diff InfoProv Source # | |
Defined in Generics.Diff.Instances | |
Diff Int16 Source # | |
Defined in Generics.Diff.Instances | |
Diff Int32 Source # | |
Defined in Generics.Diff.Instances | |
Diff Int64 Source # | |
Defined in Generics.Diff.Instances | |
Diff Int8 Source # | |
Defined in Generics.Diff.Instances | |
Diff StackEntry Source # | |
Defined in Generics.Diff.Instances Methods diff :: StackEntry -> StackEntry -> DiffResult StackEntry Source # diffList :: [StackEntry] -> [StackEntry] -> DiffResult [StackEntry] Source # | |
Diff SrcLoc Source # | |
Defined in Generics.Diff.Instances | |
Diff SomeChar Source # | |
Defined in Generics.Diff.Instances | |
Diff SomeSymbol Source # | |
Defined in Generics.Diff.Instances Methods diff :: SomeSymbol -> SomeSymbol -> DiffResult SomeSymbol Source # diffList :: [SomeSymbol] -> [SomeSymbol] -> DiffResult [SomeSymbol] Source # | |
Diff SomeNat Source # | |
Defined in Generics.Diff.Instances | |
Diff GeneralCategory Source # | |
Defined in Generics.Diff.Instances Methods diff :: GeneralCategory -> GeneralCategory -> DiffResult GeneralCategory Source # diffList :: [GeneralCategory] -> [GeneralCategory] -> DiffResult [GeneralCategory] Source # | |
Diff Word16 Source # | |
Defined in Generics.Diff.Instances | |
Diff Word32 Source # | |
Defined in Generics.Diff.Instances | |
Diff Word64 Source # | |
Defined in Generics.Diff.Instances | |
Diff Word8 Source # | |
Defined in Generics.Diff.Instances | |
Diff Timeout Source # | |
Defined in Generics.Diff.Instances | |
Diff Lexeme Source # | |
Defined in Generics.Diff.Instances | |
Diff Ordering Source # | |
Defined in Generics.Diff.Instances | |
Diff TrName Source # | |
Defined in Generics.Diff.Instances | |
Diff TyCon Source # | |
Defined in Generics.Diff.Instances | |
Diff UnicodeException Source # | |
Defined in Generics.Diff.Instances Methods diff :: UnicodeException -> UnicodeException -> DiffResult UnicodeException Source # diffList :: [UnicodeException] -> [UnicodeException] -> DiffResult [UnicodeException] Source # | |
Diff Text Source # | |
Defined in Generics.Diff.Instances | |
Diff Builder Source # | |
Defined in Generics.Diff.Instances | |
Diff Text Source # | |
Defined in Generics.Diff.Instances | |
Diff Integer Source # | |
Defined in Generics.Diff.Instances | |
Diff Natural Source # | |
Defined in Generics.Diff.Instances | |
Diff () Source # | |
Defined in Generics.Diff.Instances Methods diff :: () -> () -> DiffResult () Source # diffList :: [()] -> [()] -> DiffResult [()] Source # | |
Diff Bool Source # | |
Defined in Generics.Diff.Instances | |
Diff Char Source # | |
Defined in Generics.Diff.Instances | |
Diff Double Source # | |
Defined in Generics.Diff.Instances | |
Diff Float Source # | |
Defined in Generics.Diff.Instances | |
Diff Int Source # | |
Defined in Generics.Diff.Instances | |
Diff Word Source # | |
Defined in Generics.Diff.Instances | |
Diff (Chan a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (MutableByteArray a) Source # | |
Defined in Generics.Diff.Instances Methods diff :: MutableByteArray a -> MutableByteArray a -> DiffResult (MutableByteArray a) Source # diffList :: [MutableByteArray a] -> [MutableByteArray a] -> DiffResult [MutableByteArray a] Source # | |
Diff a => Diff (Complex a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (Identity a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (First a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (Last a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (Down a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (First a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (Last a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (Max a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (Min a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (WrappedMonoid a) Source # | |
Defined in Generics.Diff.Instances Methods diff :: WrappedMonoid a -> WrappedMonoid a -> DiffResult (WrappedMonoid a) Source # diffList :: [WrappedMonoid a] -> [WrappedMonoid a] -> DiffResult [WrappedMonoid a] Source # | |
Diff a => Diff (Dual a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (Product a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (Sum a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (ConstPtr a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (NonEmpty a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (TVar a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (ForeignPtr a) Source # | |
Defined in Generics.Diff.Instances Methods diff :: ForeignPtr a -> ForeignPtr a -> DiffResult (ForeignPtr a) Source # diffList :: [ForeignPtr a] -> [ForeignPtr a] -> DiffResult [ForeignPtr a] Source # | |
Diff (IORef a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (MVar a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (FunPtr a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (Ptr a) Source # | |
Defined in Generics.Diff.Instances | |
Eq a => Diff (Ratio a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (StablePtr a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (StableName a) Source # | |
Defined in Generics.Diff.Instances Methods diff :: StableName a -> StableName a -> DiffResult (StableName a) Source # diffList :: [StableName a] -> [StableName a] -> DiffResult [StableName a] Source # | |
Diff a => Diff (I a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff (Maybe a) Source # | |
Defined in Generics.Diff.Instances | |
Diff a => Diff [a] Source # | |
Defined in Generics.Diff.Instances Methods diff :: [a] -> [a] -> DiffResult [a] Source # diffList :: [[a]] -> [[a]] -> DiffResult [[a]] Source # | |
(Diff a, Diff b) => Diff (Either a b) Source # | |
Defined in Generics.Diff.Instances | |
(HasDatatypeInfo (Fixed a), All2 Diff (Code (Fixed a))) => Diff (Fixed a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (Proxy a) Source # | |
Defined in Generics.Diff.Instances | |
(Diff a, Diff b) => Diff (Arg a b) Source # | |
Defined in Generics.Diff.Instances | |
Diff (TypeRep a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (IOArray i e) Source # | |
Defined in Generics.Diff.Instances | |
Diff (STRef s a) Source # | |
Defined in Generics.Diff.Instances | |
(Diff a, Diff b) => Diff (a, b) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b) -> (a, b) -> DiffResult (a, b) Source # diffList :: [(a, b)] -> [(a, b)] -> DiffResult [(a, b)] Source # | |
(HasDatatypeInfo (Const a b), All2 Diff (Code (Const a b))) => Diff (Const a b) Source # | |
Defined in Generics.Diff.Instances | |
(HasDatatypeInfo (Ap f a), All2 Diff (Code (Ap f a))) => Diff (Ap f a) Source # | |
Defined in Generics.Diff.Instances | |
(HasDatatypeInfo (Alt f a), All2 Diff (Code (Alt f a))) => Diff (Alt f a) Source # | |
Defined in Generics.Diff.Instances | |
Diff (Coercion a b) Source # | |
Defined in Generics.Diff.Instances | |
Diff (OrderingI a b) Source # | |
Defined in Generics.Diff.Instances | |
Diff (STArray s i a) Source # | |
Defined in Generics.Diff.Instances | |
(HasDatatypeInfo (K a b), All2 Diff (Code (K a b))) => Diff (K a b) Source # | |
Defined in Generics.Diff.Instances | |
(Diff a, Diff b, Diff c) => Diff (a, b, c) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c) -> (a, b, c) -> DiffResult (a, b, c) Source # diffList :: [(a, b, c)] -> [(a, b, c)] -> DiffResult [(a, b, c)] Source # | |
(HasDatatypeInfo (Product f g a), All2 Diff (Code (Product f g a))) => Diff (Product f g a) Source # | |
Defined in Generics.Diff.Instances | |
(HasDatatypeInfo (Sum f g a), All2 Diff (Code (Sum f g a))) => Diff (Sum f g a) Source # | |
Defined in Generics.Diff.Instances | |
(Diff a, Diff b, Diff c, Diff d) => Diff (a, b, c, d) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d) -> (a, b, c, d) -> DiffResult (a, b, c, d) Source # diffList :: [(a, b, c, d)] -> [(a, b, c, d)] -> DiffResult [(a, b, c, d)] Source # | |
(HasDatatypeInfo (Compose f g a), All2 Diff (Code (Compose f g a))) => Diff (Compose f g a) Source # | |
Defined in Generics.Diff.Instances | |
(HasDatatypeInfo ((f :.: g) a), All2 Diff (Code ((f :.: g) a))) => Diff ((f :.: g) a) Source # | |
Defined in Generics.Diff.Instances | |
(Diff a, Diff b, Diff c, Diff d, Diff e) => Diff (a, b, c, d, e) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e) -> (a, b, c, d, e) -> DiffResult (a, b, c, d, e) Source # diffList :: [(a, b, c, d, e)] -> [(a, b, c, d, e)] -> DiffResult [(a, b, c, d, e)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f) => Diff (a, b, c, d, e, f) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f) -> (a, b, c, d, e, f) -> DiffResult (a, b, c, d, e, f) Source # diffList :: [(a, b, c, d, e, f)] -> [(a, b, c, d, e, f)] -> DiffResult [(a, b, c, d, e, f)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g) => Diff (a, b, c, d, e, f, g) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g) -> (a, b, c, d, e, f, g) -> DiffResult (a, b, c, d, e, f, g) Source # diffList :: [(a, b, c, d, e, f, g)] -> [(a, b, c, d, e, f, g)] -> DiffResult [(a, b, c, d, e, f, g)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h) => Diff (a, b, c, d, e, f, g, h) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h) -> (a, b, c, d, e, f, g, h) -> DiffResult (a, b, c, d, e, f, g, h) Source # diffList :: [(a, b, c, d, e, f, g, h)] -> [(a, b, c, d, e, f, g, h)] -> DiffResult [(a, b, c, d, e, f, g, h)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i) => Diff (a, b, c, d, e, f, g, h, i) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i) -> (a, b, c, d, e, f, g, h, i) -> DiffResult (a, b, c, d, e, f, g, h, i) Source # diffList :: [(a, b, c, d, e, f, g, h, i)] -> [(a, b, c, d, e, f, g, h, i)] -> DiffResult [(a, b, c, d, e, f, g, h, i)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j) => Diff (a, b, c, d, e, f, g, h, i, j) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j) -> (a, b, c, d, e, f, g, h, i, j) -> DiffResult (a, b, c, d, e, f, g, h, i, j) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j)] -> [(a, b, c, d, e, f, g, h, i, j)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k) => Diff (a, b, c, d, e, f, g, h, i, j, k) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k) -> (a, b, c, d, e, f, g, h, i, j, k) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k)] -> [(a, b, c, d, e, f, g, h, i, j, k)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l) => Diff (a, b, c, d, e, f, g, h, i, j, k, l) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l) -> (a, b, c, d, e, f, g, h, i, j, k, l) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l)] -> [(a, b, c, d, e, f, g, h, i, j, k, l)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m) -> (a, b, c, d, e, f, g, h, i, j, k, l, m) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q, Diff r) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q, Diff r, Diff s) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q, Diff r, Diff s, Diff t) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q, Diff r, Diff s, Diff t, Diff u) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q, Diff r, Diff s, Diff t, Diff u, Diff v) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q, Diff r, Diff s, Diff t, Diff u, Diff v, Diff w) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q, Diff r, Diff s, Diff t, Diff u, Diff v, Diff w, Diff x) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q, Diff r, Diff s, Diff t, Diff u, Diff v, Diff w, Diff x, Diff y) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y)] Source # | |
(Diff a, Diff b, Diff c, Diff d, Diff e, Diff f, Diff g, Diff h, Diff i, Diff j, Diff k, Diff l, Diff m, Diff n, Diff o, Diff p, Diff q, Diff r, Diff s, Diff t, Diff u, Diff v, Diff w, Diff x, Diff y, Diff z) => Diff (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) Source # | |
Defined in Generics.Diff.Instances Methods diff :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) -> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) -> DiffResult (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) Source # diffList :: [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)] -> [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)] -> DiffResult [(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)] Source # |
Implementing diff
gdiff :: forall a. (Generic a, HasDatatypeInfo a, All2 Diff (Code a)) => a -> a -> DiffResult a Source #
gdiffTopLevel :: forall a. (Generic a, HasDatatypeInfo a, All2 Eq (Code a)) => a -> a -> DiffResult a Source #
gdiffWith :: forall a. (Generic a, HasDatatypeInfo a) => POP Differ (Code a) -> a -> a -> DiffResult a Source #
eqDiff :: Eq a => a -> a -> DiffResult a Source #
The most basic Differ
possible. If the two values are equal, return Equal
;
otherwise, return TopLevelNotEqual
.
Types
data DiffResult a Source #
The result of a diff
.
Instances
Show (DiffResult a) Source # | |
Defined in Generics.Diff.Type Methods showsPrec :: Int -> DiffResult a -> ShowS # show :: DiffResult a -> String # showList :: [DiffResult a] -> ShowS # | |
Eq (DiffResult a) Source # | |
Defined in Generics.Diff.Type |
data DiffError a where Source #
A GADT representing an error during the diff algorithm - i.e. this tells us where and how two values differ.
The special constructors for list are so that we can treat these types a bit uniquely. See ListDiffError
.
Constructors
TopLevelNotEqual :: DiffError a | All we can say is that the values being compared are not equal. |
Nested :: DiffErrorNested (Code a) -> DiffError a | We've identified a diff at a certain constructor or field |
DiffList :: ListDiffError a -> DiffError [a] | Special case for lists |
DiffNonEmpty :: ListDiffError a -> DiffError (NonEmpty a) | Special case for non-empty lists |
data DiffErrorNested xss Source #
This is where we actually detail the difference between two values, and where in their structure the difference is.
Constructors
WrongConstructor (NS ConstructorInfo xss) (NS ConstructorInfo xss) | The two input values use different constructor, which are included. |
FieldMismatch (DiffAtField xss) | The inputs use the same constructor, but differ at one of the fields.
|
Instances
Show (DiffErrorNested xss) Source # | |
Defined in Generics.Diff.Type Methods showsPrec :: Int -> DiffErrorNested xss -> ShowS # show :: DiffErrorNested xss -> String # showList :: [DiffErrorNested xss] -> ShowS # | |
Eq (DiffErrorNested xss) Source # | |
Defined in Generics.Diff.Type Methods (==) :: DiffErrorNested xss -> DiffErrorNested xss -> Bool # (/=) :: DiffErrorNested xss -> DiffErrorNested xss -> Bool # |
data ListDiffError a Source #
If we did a normal gdiff
on a linked list, we'd have to recurse through one "level" of
Diff
s for each element of the input lists. The output would be really hard to read or understand.
Therefore this type lets us treat lists as a special case, depending on how they differ.
Constructors
DiffAtIndex Int (DiffError a) | If we find a difference when comparing the two lists pointwise, we report the index of the error and the error caused by the elements at that index of the input lists. |
WrongLengths Int Int | The two lists have different lengths. If we get a |
Instances
Show (ListDiffError a) Source # | |
Defined in Generics.Diff.Type Methods showsPrec :: Int -> ListDiffError a -> ShowS # show :: ListDiffError a -> String # showList :: [ListDiffError a] -> ShowS # | |
Eq (ListDiffError a) Source # | |
Defined in Generics.Diff.Type Methods (==) :: ListDiffError a -> ListDiffError a -> Bool # (/=) :: ListDiffError a -> ListDiffError a -> Bool # |
newtype DiffAtField xss Source #
In the case that two values have the same constructor but differ at a certain field, we want two
report two things: what the DiffError
is at that field, and exactly where that field is. Careful use
of NS
gives us both of those things.
Constructors
DiffAtField (NS (ConstructorInfo :*: NS DiffError) xss) |
Instances
Show (DiffAtField xss) Source # | |
Defined in Generics.Diff.Type Methods showsPrec :: Int -> DiffAtField xss -> ShowS # show :: DiffAtField xss -> String # showList :: [DiffAtField xss] -> ShowS # | |
Eq (DiffAtField xss) Source # | |
Defined in Generics.Diff.Type Methods (==) :: DiffAtField xss -> DiffAtField xss -> Bool # (/=) :: DiffAtField xss -> DiffAtField xss -> Bool # |
data (f :*: g) a infixr 6 Source #
Lifted product of functors. We could have used Product
, but this is more concise.
Constructors
(f a) :*: (g a) infixr 6 |
A newtype wrapping a binary function producing a DiffResult
.
The only reason for this newtype is so that we can use it as a functor with the types from
generic-sop
.
Constructors
Differ (x -> x -> DiffResult x) |