Skip to content

Remove unsafeCoerce from appendIndices and fix tests with GHC 9.0.1#397

Merged
arybczak merged 5 commits intomasterfrom
no-unsafe-coerce-new
Feb 8, 2021
Merged

Remove unsafeCoerce from appendIndices and fix tests with GHC 9.0.1#397
arybczak merged 5 commits intomasterfrom
no-unsafe-coerce-new

Conversation

@arybczak
Copy link
Collaborator

@arybczak arybczak commented Feb 4, 2021

Fixes #396.

This doesn't slow compilation, I tested with a big project.

@arybczak arybczak force-pushed the no-unsafe-coerce-new branch 3 times, most recently from 5c1ef7c to 672b751 Compare February 5, 2021 00:31
@arybczak arybczak changed the title Remove unsafeCoerce from appendIndices Remove unsafeCoerce from appendIndices and fix tests with GHC 9.0.1 Feb 5, 2021
@arybczak arybczak force-pushed the no-unsafe-coerce-new branch 4 times, most recently from ccee7c8 to 1b41232 Compare February 5, 2021 02:45
@phadej
Copy link
Contributor

phadej commented Feb 5, 2021

Let's see after INLINEs are removed.

@arybczak
Copy link
Collaborator Author

arybczak commented Feb 5, 2021

I also tried that with the inlineless branch and it was fine 👍


-- | Tagged version of 'Data.Type.Equality.(:~:)' for carrying evidence that two
-- index lists in a curried form are equal.
data IxEq i is js where
Copy link
Contributor

Choose a reason for hiding this comment

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

This is nice.

--
infixl 9 %
(%) :: (Is k m, Is l m, m ~ Join k l, ks ~ Append is js)
(%) :: (Is k m, Is l m, m ~ Join k l, AppendIndices is js, ks ~ Append is js)
Copy link
Member

Choose a reason for hiding this comment

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

I think this is generally a good idea, but the only thing that is a slight shame is making the type of % more complicated, with AppendIndices potentially showing up in inferred types. Perhaps it is worth making AppendIndices takes ks as a parameter so that AppendIndices is js ks can imply ks ~ Append is js?

Copy link
Contributor

@phadej phadej Feb 5, 2021

Choose a reason for hiding this comment

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

One could maybe get rid of Append family all together, by having

-appendIndices :: IxEq i (Curry xs (Curry ys i)) (Curry (Append xs ys) i)
+appendIndices :: IxEq i (Curry xs (Curry ys i)) (Curry zs i)

... but I guess we cannot as there is no sane way to break functional dependencies in GHCs. Edit i.e. having overlapping FD i.e. the additional incoherent AppendIndicies xs [] xs, if AppendIndicies is js ks | is js -> ks

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Perhaps it is worth making AppendIndices takes ks as a parameter

That's what I've done in #353, but then you pointed out here that GHC expands ks to be Append is js and removing it would be better ;)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

One could maybe get rid of Append family all together

I tried that and looks like it works, so I re-added the third parameter and removed dependence on Append.


-- | If we know the second list is empty, we can pick the first list without
-- knowing anything about it, hence the instance is marked as INCOHERENT.
instance {-# INCOHERENT #-} AppendIndices xs '[] where
Copy link
Contributor

@phadej phadej Feb 6, 2021

Choose a reason for hiding this comment

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

Oh, I thought that FunctionalDependencies would choke on this? Is INCOHERENT making it work somehow?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's not INCOHERENT, it's just that the consistency check for fundeps is quite lenient.


instance AppendIndices xs ys ks => AppendIndices (x ': xs) ys (x ': ks) where
appendIndices :: forall i. IxEq i (Curry (x ': xs) (Curry ys i)) (Curry (x ': ks) i)
appendIndices | IxEq <- appendIndices @xs @ys @ks @i = IxEq
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks very nice. 👍

@arybczak
Copy link
Collaborator Author

arybczak commented Feb 6, 2021

It's worth noting that due to % being infixl when composing multiple indexed optics the behaviour of AppendIndices is quadratic 🤔

Though that shouldn't be a problem in practice since I doubt anyone uses >5 indices in a single pipeline.

@phadej
Copy link
Contributor

phadej commented Feb 6, 2021

re quadratic: wasn't that the case with Append also?

@arybczak
Copy link
Collaborator Author

arybczak commented Feb 6, 2021

Oh, you're right. I thought unsafeCoerce saved us there before, but indeed Append was still quadratic.

@arybczak arybczak force-pushed the no-unsafe-coerce-new branch from 0cfcb8a to 64c136e Compare February 8, 2021 12:13
@arybczak
Copy link
Collaborator Author

arybczak commented Feb 8, 2021

Testing with no INLINE pragmas passed, so I'm merging.

@arybczak arybczak merged commit 1fd0a8c into master Feb 8, 2021
@arybczak arybczak deleted the no-unsafe-coerce-new branch February 8, 2021 20:59
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.

Tests fail with 9.0.1 because of unsafeEqualityProof

3 participants