Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplement MapWithWithMove in terms of MapWithPatchingMove #14

Merged
merged 20 commits into from
May 22, 2021

Conversation

Ericson2314
Copy link
Member

@Ericson2314 Ericson2314 commented Jan 22, 2020

Per the change log, care is taken so this should not be a breaking change.

I had to to write explicit export lists to get around some obscure GHC bugs with reexport data types twice with different patterns nested for (..) imports, but I think it's nicer anyways as it makes comparability easier to check going forward.

@Ericson2314
Copy link
Member Author

Looks like a haddock or, less likely, GHC bug. Ugh!

- Do explicit export lists. This is a chore now, but makes managing
  Compatibility easier later.

- Make `MapWithMove`'s `From` a proper newtype. This improves the
  compatibility and type error situation.

- Work around GHC export list bug: the explicit export lists without big
  reexports this this for us, in fact.
This makes an instance, no new export needed.
- `mplus` -> `mappen`

- better coverage
@Ericson2314 Ericson2314 force-pushed the patch-map-inner-patch-desugar branch from 20531ce to 32a1f2f Compare April 22, 2021 23:15
newtype PatchMapWithMove k v = PatchMapWithMove
{ -- | Extract the internal representation of the 'PatchMapWithMove'
unPatchMapWithMove :: Map k (NodeInfo k v)
newtype PatchMapWithMove k (v :: Type) = PatchMapWithMove'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PolyKinds was mischievously generalizing this over things for which PatchTarget (Proxy v) is undefined. Oh type families...

Comment on lines +312 to +352
--
-- From
--

-- | Describe how a key's new value should be produced
data From k p
= From_Insert (PatchTarget p) -- ^ Insert the given value here
| From_Delete -- ^ Delete the existing value, if any, from here
| From_Move !k !p -- ^ Move the value here from the given key, and apply the given patch

deriving instance (Show k, Show p, Show (PatchTarget p)) => Show (From k p)
deriving instance (Read k, Read p, Read (PatchTarget p)) => Read (From k p)
deriving instance (Eq k, Eq p, Eq (PatchTarget p)) => Eq (From k p)
deriving instance (Ord k, Ord p, Ord (PatchTarget p)) => Ord (From k p)

-- | Traverse the 'From' over the key, patch, and patch target. Because of
-- the type families here, this doesn't it any bi- or tri-traversal class.
bitraverseFrom
:: Applicative f
=> (k0 -> f k1)
-> (p0 -> f p1)
-> (PatchTarget p0 -> f (PatchTarget p1))
-> From k0 p0 -> f (From k1 p1)
bitraverseFrom fk fp fpt = \case
From_Insert pt -> From_Insert <$> fpt pt
From_Delete -> pure From_Delete
From_Move k p -> From_Move <$> fk k <*> fp p

--
-- To
--

-- | Describe where a key's old value will go. If this is 'Just', that means
-- the key's old value will be moved to the given other key; if it is 'Nothing',
-- that means it will be deleted.
type To = Maybe

--
-- Fixup
--

Copy link
Member Author

@Ericson2314 Ericson2314 Apr 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just rearranging

Comment on lines 266 to 295
--
-- NodeInfo
--

-- | Holds the information about each key: where its new value should come from,
-- and where its old value should go to
data NodeInfo k p = NodeInfo
{ _nodeInfo_from :: !(From k p)
-- ^ Where do we get the new value for this key?
, _nodeInfo_to :: !(To k)
-- ^ If the old value is being kept (i.e. moved rather than deleted or
-- replaced), where is it going?
}
deriving instance (Show k, Show p, Show (PatchTarget p)) => Show (NodeInfo k p)
deriving instance (Read k, Read p, Read (PatchTarget p)) => Read (NodeInfo k p)
deriving instance (Eq k, Eq p, Eq (PatchTarget p)) => Eq (NodeInfo k p)
deriving instance (Ord k, Ord p, Ord (PatchTarget p)) => Ord (NodeInfo k p)

-- | Traverse the 'NodeInfo' over the key, patch, and patch target. Because of
-- the type families here, this doesn't it any bi- or tri-traversal class.
bitraverseNodeInfo
:: Applicative f
=> (k0 -> f k1)
-> (p0 -> f p1)
-> (PatchTarget p0 -> f (PatchTarget p1))
-> NodeInfo k0 p0 -> f (NodeInfo k1 p1)
bitraverseNodeInfo fk fp fpt (NodeInfo from to) = NodeInfo
<$> bitraverseFrom fk fp fpt from
<*> traverse fk to

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just rearranging

Comment on lines -58 to -106
-- | Holds the information about each key: where its new value should come from,
-- and where its old value should go to
data NodeInfo k p = NodeInfo
{ _nodeInfo_from :: !(From k p)
-- ^ Where do we get the new value for this key?
, _nodeInfo_to :: !(To k)
-- ^ If the old value is being kept (i.e. moved rather than deleted or
-- replaced), where is it going?
}
deriving instance (Show k, Show p, Show (PatchTarget p)) => Show (NodeInfo k p)
deriving instance (Read k, Read p, Read (PatchTarget p)) => Read (NodeInfo k p)
deriving instance (Eq k, Eq p, Eq (PatchTarget p)) => Eq (NodeInfo k p)
deriving instance (Ord k, Ord p, Ord (PatchTarget p)) => Ord (NodeInfo k p)

bitraverseNodeInfo
:: Applicative f
=> (k0 -> f k1)
-> (p0 -> f p1)
-> (PatchTarget p0 -> f (PatchTarget p1))
-> NodeInfo k0 p0 -> f (NodeInfo k1 p1)
bitraverseNodeInfo fk fp fpt (NodeInfo from to) = NodeInfo
<$> bitraverseFrom fk fp fpt from
<*> traverse fk to

-- | Describe how a key's new value should be produced
data From k p
= From_Insert (PatchTarget p) -- ^ Insert the given value here
| From_Delete -- ^ Delete the existing value, if any, from here
| From_Move !k !p -- ^ Move the value here from the given key, and apply the given patch

bitraverseFrom
:: Applicative f
=> (k0 -> f k1)
-> (p0 -> f p1)
-> (PatchTarget p0 -> f (PatchTarget p1))
-> From k0 p0 -> f (From k1 p1)
bitraverseFrom fk fp fpt = \case
From_Insert pt -> From_Insert <$> fpt pt
From_Delete -> pure From_Delete
From_Move k p -> From_Move <$> fk k <*> fp p

deriving instance (Show k, Show p, Show (PatchTarget p)) => Show (From k p)
deriving instance (Read k, Read p, Read (PatchTarget p)) => Read (From k p)
deriving instance (Eq k, Eq p, Eq (PatchTarget p)) => Eq (From k p)
deriving instance (Ord k, Ord p, Ord (PatchTarget p)) => Ord (From k p)

-- | Describe where a key's old value will go. If this is 'Just', that means
-- the key's old value will be moved to the given other key; if it is 'Nothing',
-- that means it will be deleted.
type To = Maybe

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just rearranging, see below

Comment on lines +46 to +47
- name: Build Docs
run: cabal haddock
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Travis was doing this, so this is a good idea if we want to be able to drop travis.

Copy link
Member

@ryantrinkle ryantrinkle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@Ericson2314 Ericson2314 merged commit 0019cce into develop May 22, 2021
@Ericson2314 Ericson2314 deleted the patch-map-inner-patch-desugar branch May 22, 2021 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants