GithubHelp home page GithubHelp logo

purescript-leibniz's Introduction

purescript-leibniz

Latest release Build Status

Leibniz equality.

Installation

bower install purescript-leibniz

Documentation

Module documentation is published on Pursuit.

purescript-leibniz's People

Contributors

garyb avatar paf31 avatar rgrempel avatar risto-stevcev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

purescript-leibniz's Issues

Add "refute"

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))

Add missing relations

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.

`inner` and `outer`

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 have

Either 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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.