## New Syntax for Abstract Refinements ### Ghost Parameters ```haskell A n -> B (n + 1) -- becomes { p n => q (n + 1)}. A
-> B -> B -> B -> B >) -> xs:List a -> (Count (List b) < -> B -> B |- {v:Int | v = n+1} <: Int |- {v:Int | v = n + 1} <: Int ) -> Int |- {v:Int | v = len xs} <: Int ) -> Int , m::Int ) -> (Int -> Int Bool>. [Int ] -> Int
```
can just be written as
```haskell
foo :: forall . [p] -> p
```
where we need not write `Int `, its enough to just write `p`.
#### Step 2: An explicit "Meet" Operator
However, sometimes you need to write things like:
```haskell
List a < >
```
where `p :: List a -> Bool` i.e. `p :: {List a}` and which denotes
* a list-of-a that is recursively indexed by `p`, AND
* where the top-level list is constrained by `p`.
That is, more generally, where you want to
* additionally, index the type with other abstract refinements, AND
* "apply" an abstract refinement to the "top-level" type.
For this, I think we should have an explicit *meet* operator
Note that, earlier `Int ` was an *implicit* meet operator,
where we were *conjoining* `Int` and `p`. Viewing `p` as
just being a refined `Int` allows us to SEPARATE "meet"
to only those places where its really needed.
So we can write the funny `List a < >` as:
```haskell
p /\ List a
```
See below for many other examples:
#### Example: Value Dependencies
**Old**
```haskell
foo :: forall Int -> Bool>. x:Int -> [Int ] -> Int
```
**New**
```haskell
foo :: forall {Int}>. x:Int -> [p x] -> p x
```
#### Example: Dependent Pairs
**Old**
```haskell
data Pair a b b -> Bool>
= Pair { pairX :: a
, pairB :: b
}
type OrdPair a = Pair <{\px py -> px < py}> a a
```
**New**
```haskell
data Pair a b {b}>
= Pair { pairX :: a
, pairY :: p pairX
}
type OrdPair a = Pair a a <\px -> {py:a | px < py}>
```
#### Example: Binary Search Maps
**Old**
```haskell
data Map k a a -> Bool>
= Emp
| Cons { lHd :: a
, lTl :: List (a )
}
type OList a = List <{\x v -> x <= v}> a
```
**New**
```haskell
data List a {a}>
= Emp
| Cons { lHd :: a
, lTl :: List (p lHd)
}
type OList a = List a <\x -> {v:a | x <= v}>
```
#### Example: Infinite Streams
**Old**
```haskell
data List a Prop>
= N
| C { x :: a
, xs :: List a < >
}
type Stream a = {xs: List <{\v -> isCons v}> a | isCons xs}
```
**New**
```haskell
data List a
= N
| C { x :: a
, xs :: p /\ List a
}
type Stream a = {xs: List a <{v | isCons v}> | isCons xs}
```
### Old Proposal
| | Current Syntax | Future Syntax |
|----------------------|-------------------------------|-------------------------------|
| Abstract Refinements | `List <{\x v -> v >= x}> Int` | `List Int (\x v -> v >= x)` |
| | `[a ]<{\x v -> v >= x}>` | `[a p] (\x v -> v >= x) (??)` |
| | `Int ` | `Int p` |
| | `Int<\x -> x >=0>` | `Int (\x -> x >= 0)` |
| | `Maybe < > (a > k v (?)` | `Maybe k v l r p` |
| Type Arguments | `ListN a {len xs + len ys}` | `ListN a (len xs + len ys)` |
Q: How do I distinguish `Int p` with `ListN a n`?
(`p` is a abstract refinement and `n` is an `Integer`)
A: From the context!
Use simple kinds, i.e.
`ListN :: * -> Int -> *`
`Int :: ?AR -> *`
-- i.e.
{ p n => v = n + 1 => q v}. A
```
which means, I suppose that
```haskell
A n -> B (op n)
-- becomes
{ p n => q (op n) }. A
-- i.e.
{ p n => v = op n => q v }. A
```
(a -> Count b <
>)
```haskell
A n -> B m -> C (n + m)
-- becomes
{ p n => q m => r (n + m) }. A
-> C
-> C
}
```haskell
{-@ bump1 :: forall
}
(Int -> Int
@-}
bump1 :: (Int -> Int) -> Int
bump1 f = f 0 + 1
{-@ bumps :: forall
}
(Int -> [Int]
@-}
bumps :: (Int -> ListN Int n) -> IntN n
bumps f = size (f 0)
{-@ bump2 :: forall
|- {v:Int | v = n + m} <: Int
) -> Int
) (?)` | `Maybe (a q) p` |
| | `Map