[darcs-devel] darcs patch: add context to HashedRepo.copy_repo (and 2 more)
David Roundy
droundy at darcs.net
Mon Mar 17 15:45:24 UTC 2008
On Wed, Mar 12, 2008 at 03:30:50PM -0700, Jason Dagit wrote:
> On Wed, Mar 12, 2008 at 6:48 AM, David Roundy <droundy at darcs.net> wrote:
> > I don't think you should ever need an unsafeCoerceP just to read
> > patches into a sequence using createHashed. That's why a sealed patch
> > has only one of its two contexts sealed.
> >
> > Oh, I see the trouble: it's that you want to constrain the final state.
>
> I'm not sure what you mean. This isn't about the difference of read_repo
> and read_tenative_repo. It's about getting enough context to parse,
> read_patches, rp and createHashed so that the resulting patches can be
> placed into a sequence.
As you will see in my previous email (responding to your later email), we
can implement read_repo_private without any unsafeCoerceP.
> > Were there more unsafeCoerceP's that you needed to add? I'm really
> > feeling doubtful that this Context approach is the way to go. You
> > can't remove the use of unsafe operations from HashedRepo, because that
> > is where high-level invariant properties of repositories are defined.
>
> There are 4 more unsafeCoercePs that would have been needed in
> read_repo_private. That's what I've been trying to explain by talking about
> parse, createHashed, read_patches and rp. If you look at the code prior to
> this patch bundle you'll see a few things. Currently read_patches and rp
> try to allow an existentially quantified type variable to escape (it may
> help to see the exact compiler message yourself, this is easy to reproduce,
> look at the patch bundle I sent in that uses unsafeCoerceP instead of
> Context for details).
>
> Or in other words, when we unseal the result of createHashed (even if we put
> it into a sequence as we unseal it), the type checker complains that the
> previously sealed phantom type is going to escape this context. That gives
> us 4 places in read_repo_private that requires an unsafeCoerceP.
I agree that read_repo_private should be implemented (and implementable) safely.
> > No, there's no guarantee that Context just manipulates phantom types.
> > unsafeContext can create concrete types, so you could write (this is
> > pseudocode):
>
> I'm still not convinced that unsafeContext can allow us manipulate
> non-phantom types in an unsafe way. For example, wrapping the identity
> function in a Context gives, Context id :: Context (a -> a) x y (I tested
> this in ghci). Then as soon as you unwrap it to use the identity function
> the phantom types are gone and you can't play with them anymore. If you've
> seen something about this in the literature I'd be happy to go learn about
> it. I don't think my arguments about type theory are sophisticated enough
> to come up with the necessary proofs unassisted to demonstrate the safety or
> unsafety here.
>
> > unsafeCoerce# :: a -> b
> > unsafeCoerce# x = fromJust $ do let myid = identity
> > h = unsafeContext (hash myid)
> > p = createHashed h (parse $ showPatch myid)
> > IsEq <- sloppy_identity p
> > return x
> >
> > and you've got an inplementation of unsafeCoerce# (which never returns
> > Nothing).
>
> If I'm understanding your pseudo code correctly, (and I pulled the type for
> `hash` out of the source), I get something like the following. I'm assuming
> that identity is of the type that hash takes, but represents an identity
> patch. Maybe that's not what you meant?
>
> Maybe you meant for it to work like this (ignoring IO):
> h :: Context Int32 C(x y) -- x and y are arbitrary, we know x == y, but the
> type checker doesn't
no, x /= y, and we know that. x == a, and y == b.
> p :: ReadPatch p => Hopefully p C(x y)
> I can see how this would then match for the pattern "IsEq <- sloppy_identity
> p", since p was created from the string representing the identity patch. I
> fail to see how the overall type could be "a -> b". We do all of that work
> and then return x, which we already stated to have type 'a'. Or am I
> missing something?
IsEq proves that type x and type y are the same, but since x is a and y is
b, we've proven that type a and b are the same. Thus we're able to return
our input of type a as if it were type b!
> I'm attempting to implement this, and I have this defined inside of
> read_repo_private:
> _myCoerce :: a -> b
> _myCoerce x = fromJust $
> do let h = unsafeContext ""
> s = unsafeContext idpatchinfo
> p = (unsafePerformIO $ createHashed h (parse $ s))
> pai = idpatchinfo `patchInfoAndPatch` p :: PatchInfoAnd
> Prim C(x y)
> IsEq <- return $ sloppyIdentity pai
> return x
>
> The _ is just there to stifle warnings about not using myCoerce and I'm
> using idpatchinfo defined in Darcs.Patch.Info. Also for h I just use the
> empty string since I'm really only interested in getting this to type check.
>
> You'll notice I changed it a fair but, but all my changes are just there to
> get it as close to compiling as possible. I even threw in an
> unsafePerformIO and the type checker tells me that a and b do not unify. So
> it seems that it would still behave as the identity function even though it
> may be a bit unsafe internally. Perhaps I'm taking the formal parameter 'x'
> too literally here? You did say it was pseudo code, but my version has this
> error:
> src/Darcs/Repository/HashedRepo.lhs:214:24:
> Couldn't match expected type `b' (a rigid variable)
> against inferred type `a' (a rigid variable)
> `b' is bound by the type signature for `_myCoerce'
> at src/Darcs/Repository/HashedRepo.lhs:213:28
> `a' is bound by the type signature for `_myCoerce'
> at src/Darcs/Repository/HashedRepo.lhs:213:23
I think we may need to add some type signatured and scoped types to the
above code to make it work (but I still haven't tested this)
_myCoerce :: forall a b. a -> b
_myCoerce = do let h = unsafeContext "" :: Context String a b
Actually, probably all you need to do is to change your pai to be of type
PatchInfoAnd Prim C(a b). (and add the forall, to get lexical type
scoping)
--
David Roundy
Department of Physics
Oregon State University
More information about the darcs-devel
mailing list