purescript-leibniz
Leibniz equality.
Installation
bower install purescript-leibniz
Documentation
Module documentation is published on Pursuit.
Leibniz Equality
License: BSD 3-Clause "New" or "Revised" License
Leibniz equality.
bower install purescript-leibniz
Module documentation is published on Pursuit.
This will be possible in 0.12 thanks to instance chains:
class Distinguish a b c o | a b c -> o
instance distinguishLeft :: Distinguish a b a Unit else
instance distinguishRight :: Distinguish a b b r
foreign import data Distinguished :: Type -> Type -> Type -> Type
distinguished :: forall a b c r. Distinguish a b c r => r -> Distinguished a b c
distinguished = unsafeCoerce
unDistinguished :: forall a b c r. Distinguish a b c r => Distinguished a b c -> r
unDistinguished = unsafeCoerce
refute :: forall a b r. Distinguish a b b r => a ~ b -> r
refute l = unDistinguished (runLeibniz l (distinguished unit :: Distinguished a b a))
Inspired by this discussion.
trans :: forall a b c. a ~ b -> b ~ c -> a ~ c
Also, generalizing the higher-kinded lower functions:
lowerLeibniz2' :: forall f a b c d. f a b ~ f c d -> Tuple (a ~ c) (b ~ d)
e.g. for f
that is Tuple
, Either
, etc., and so on.
In some code I was working on, I needed (wanted?) to define these two functions:
inner :: ∀ f g a b. (f a ~ g b) -> (a ~ b)
inner _ = Leibniz unsafeCoerce
outer :: ∀ f g a b c. (f a ~ g b) -> (f c ~ g c)
outer _ = Leibniz unsafeCoerce
(In fact, I only really needed inner
). These are like lowerLeibniz
and liftLeibniz
, except that the type signature is a bit relaxed -- e.g. lowerLeibniz
more strictly requires (f a ~ f b) -> (a ~ b)
, where the constructors must match.
The implementation of inner
and outer
are, of course, trivial (in one sense) -- the question is whether it is justified. (That is, whether the unsafeCoerce
is a shortcut for a conclusion we are justified in reaching).
The Haskell version of the Leibniz library does limit itself to f a ~ f b -> a ~ b
... that is, the constructors must match, so that may mean there is a problem with my inner
.
However, the Haskell GADT library defines exactly my inner
and outer
(well, I translated outer
a bit in the absence of polykinds).
Of course, that could be due to some advantage which GADTs have over Leibniz equality. However, Sulzmann and Wang's paper "GADTless Programming in Haskell 98" has a discussion of what amounts to inner
at pp. 12-13. In fact, at the bottom of p. 12, it states my particular use-case fairly precisely -- that is, I have two types in which I've "forgotten" both the constructor and the type it is applied to, but I know they are both equal to a third type.
The second two last function clauses are interesting. The patterns of the
first and second argument constrain k to Either k1 k2 and Either k1’ k2’,
respectively. Hence, we haveEither k1 k2 = k = Either k1' k2'
from which we can follow k1 = k1' and k2 = k2'
If I'm following Sulzmann and Wang's discussion at the top of p. 13 correctly, they are saying that you can't implement inner
with a newtype
approach, but you can do it with a (less efficient) series of explicit coercions (they give more details in their Appendix A). I can't say I actually follow the discussion entirely, but it seems as though they are arguing that something like inner
is correctly definable (in Haskell 98). In a sense, it's just that conclusion that matters for our purposes, since it's trivially definable with unsafeCoerce
... it's just a question of whether it justifiable to take that shortcut, and I think they are arguing that it is.
Anyway, what I'm suggesting is that perhaps inner
and outer
could be added here (or, one could relax the type signatures for liftLeibniz
and lowerLeibniz
). But, of course, that depends on a judgment that the inference they would express is indeed sound.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.