-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy patharrow-notation.trac
78 lines (61 loc) · 4.1 KB
/
arrow-notation.trac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
= Arrow notation =
Arrow notation ([http://www.haskell.org/ghc/docs/latest/html/users_guide/arrow-notation.html current documentation]) has been in GHC for many years, but it lacks a maintainer. Even Simon PJ is very hazy about how it all works, and even toys with the idea of taking it out altogether.
Apart from the tickets below, there are a number of things that need doing
* There no single place that describes all the moving parts of the arrow implementation, including both the typechecking and desugaring rules -- and it's very hard to work it out from the code. Simply writing out the typechecking and desugaring rules, with some commentary, would be really helpful. There is a tiny start in `Note [Arrow overview]` in `TcArrows`.
* #13547: work out if existential and GADT pattern matches are allowed. If so, fix the desugarer; if not, reject them with a decent error message, not a Core Lint crash.
* See the discussion on this [https://mail.haskell.org/pipermail/ghc-devs/2016-December/013317.html Dec 16 ghc-devs thread]. It started with a desire to support rebindable syntax.
* Lower down this page are a couple of proposed changes to the notation enabled with `-XArrows`. I'm not sure of their status.
== Tickets ==
Use Keyword = `Arrows` to ensure that a ticket ends up on these lists.
'''Open Tickets:'''
[[TicketQuery(status=new|patch,keywords=~Arrows)]]
'''Closed Tickets:'''
[[TicketQuery(status=closed,keywords=~Arrows)]]
== Changing the types of arrow operators (implemented in March 2013, for GHC 7.8) ==
Currently, the type of each argument of an operator (and its result) is required to have the form
{{{
a (...(e,t1), ... tn) t
}}}
where `e` is a polymorphic type variable shared by all these types, but the arrow types `a` can vary. The ''User's Guide'' has these examples:
{{{
ArrowPlus a => (<+>) :: a e c -> a e c -> a e c
untilA :: ArrowChoice a => a e () -> a e Bool -> a e ()
handleA :: ... => a e c -> a (e,Ex) c -> a e c
bracketA :: ... => a e b -> a (e,b) c -> a (e,c) d -> a e d
runReader :: ... => a e c -> a' (e,State) c
runState :: ... => a e c -> a' (e,State) (c,State)
bind :: Arrow a => a e b -> a (e,b) c -> a e c
bind_ :: Arrow a => a e b -> a e c -> a e c
cond :: ArrowChoice a => a e b -> a e b -> a (e,Bool) b
}}}
The problem is that to work out how many `ti`s there are, the type checker needs to be able to determine whether a type is a pair type or this Skolem variable `e`, and this can't be done with GHC's new constraint-based type system.
The plan is to re-arrange the shapes of the argument and result types to
{{{
a (e, (t1, ... (tn, ())...)) t
}}}
For the above examples, the new types will be
{{{
ArrowPlus a => (<+>) :: a (e,()) c -> a (e,()) c -> a (e,()) c
untilA :: ArrowChoice a => a (e,()) () -> a (e,()) Bool -> a (e,()) ()
handleA :: ... => a (e,()) c -> a (e,(Ex,())) c -> a (e,()) c
bracketA :: ... => a (e,()) b -> a (e,(b,())) c -> a (e,(c,())) d -> a (e,()) d
runReader :: ... => a (e,()) c -> a' (e,(State,())) c
runState :: ... => a (e,()) c -> a' (e,(State,())) (c,State)
bind :: Arrow a => a (e,()) b -> a (e,(b,())) c -> a (e,()) c
bind_ :: Arrow a => a (e,()) b -> a (e,()) c -> a (e,()) c
cond :: ArrowChoice a => a (e,()) b -> a (e,()) b -> a (e,(Bool,())) b
}}}
Now in the cases of `(<+>)`, `untilA` and `bind`, the new types are specializations of the old, so those operators will still work, but the others will need to be re-defined with the new types.
== Generalizing the types of commands ==
The translation of many of the different varieties of command does not require the full `Arrow` class, but rather just
{{{
premap :: Arrow a => (b -> b') -> a b' c -> a b c
premap f g = arr f >>> g
}}}
So the proposal is to introduce a superclass of `Arrow` with just this:
{{{
class PreArrow a where
premap :: Arrow a => (b -> b') -> a b' c -> a b c
}}}
and require that class instead of `Arrow` for the types of those constructs. ([http://thread.gmane.org/gmane.comp.lang.haskell.libraries/17609 libraries proposal])
This shouldn't break any code that uses arrows, but will require rewriting of instances of `Arrow`.