on master help sign in
Merge pull request #2232 from david-christiansen/agda-style-records
5e239baDavid Christiansen
CHANGELOG+4
@@ -36,6 +36,10 @@ New in 0.9.18:
36 "n". If "n" is lexically bound, then the resulting quotation will be for it,
36 "n". If "n" is lexically bound, then the resulting quotation will be for it,
37 whereas if it is not, then it will succeed with a quotation of the unique
37 whereas if it is not, then it will succeed with a quotation of the unique
38 global name that matches.
38 global name that matches.
39+* New syntax for records that closely matches our other record-like structures:
40+ type classes. See the updated tutorial for details.
41+* Records can be coinductive. Define coinductive records with the "corecord"
42+ keyword.
39* if ... then ... else ... is now built-in syntax instead of being defined in
43* if ... then ... else ... is now built-in syntax instead of being defined in
40 a library. It is shown in REPL output and error messages, rather than its
44 a library. It is shown in REPL output and error messages, rather than its
41 desugaring.
45 desugaring.
docs/reference/documenting.rst+5−5
@@ -127,9 +127,9 @@ italics correctly). A comprehensive set of examples is given below.
127 ||| @ rest the remaining work
127 ||| @ rest the remaining work
128 Later : (rest : Partial a) -> Partial a
128 Later : (rest : Partial a) -> Partial a
129
129
130− ||| We can document records just like normal data
130+ ||| We can document records, including their fields and constructors
131− record Yummy : Type where
131+ record Yummy where
132−
133 ||| Make a yummy
132 ||| Make a yummy
133+ constructor MkYummy
134− ||| @ food what to eat
134+ ||| What to eat
135− MkYummy : (food : String) -> Yummy
135+ food : String
docs/reference/ffi.rst+6−5
@@ -70,21 +70,22 @@ call:
70
70
71.. code-block:: idris
71.. code-block:: idris
72
72
73− record FFI : Type where
73+ record FFI where
74+ constructor MkFFI
74− MkFFI : (ffi_types : Type -> Type) ->
75+ ffi_types : Type -> Type
75− (ffi_fn : Type) -> FFI
76+ ffi_fn : Type
76
77
77For C, this is:
78For C, this is:
78
79
79.. code-block:: idris
80.. code-block:: idris
80
81
81− -- Supported C integer types
82+ ||| Supported C integer types
82 data C_IntTypes : Type -> Type where
83 data C_IntTypes : Type -> Type where
83 C_IntChar : C_IntTypes Char
84 C_IntChar : C_IntTypes Char
84 C_IntNative : C_IntTypes Int
85 C_IntNative : C_IntTypes Int
85 ... -- more integer types
86 ... -- more integer types
86
87
87− -- Supported C foreign types
88+ ||| Supported C foreign types
88 data C_Types : Type -> Type where
89 data C_Types : Type -> Type where
89 C_Str : C_Types String
90 C_Str : C_Types String
90 C_Float : C_Types Float
91 C_Float : C_Types Float
docs/tutorial/typesfuns.rst+46−17
@@ -979,18 +979,19 @@ example, we can represent a person's name and age in a record:
979
979
980.. code-block:: idris
980.. code-block:: idris
981
981
982− record Person : Type where
982+ record Person where
983+ constructor MkPerson
983− MkPerson : (name : String) ->
984+ name : String
984− (age : Int) -> Person
985+ age : Int
985
986
986 fred : Person
987 fred : Person
987 fred = MkPerson "Fred" 30
988 fred = MkPerson "Fred" 30
988
989
989−Record declarations are like ``data`` declarations, except that they
990+Records can have *parameters*, which are listed between the record
990−are introduced by the ``record`` keyword, and can only have one
991+name and the ``where`` keyword, and *fields*, which are in an indented
991−constructor. The names of the binders in the constructor type
992+block following the `where` keyword (here, ``name`` and ``age``). The
992−(``name`` and ``age``) here are the field names, which we can use to
993+constructor name is provided after the ``constructor`` keyword. The
993−access the field values:
994+field names can be used to access the field values:
994
995
995::
996::
996
997
@@ -1002,7 +1003,8 @@ access the field values:
1002 name : Person -> String
1003 name : Person -> String
1003
1004
1004We can also use the field names to update a record (or, more
1005We can also use the field names to update a record (or, more
1005−precisely, produce a new record with the given fields updated).
1006+precisely, produce a copy of the record with the given fields
1007+updated):
1006
1008
1007.. code-block:: bash
1009.. code-block:: bash
1008
1010
@@ -1016,15 +1018,14 @@ updates the given fields in a record.
1016
1018
1017Records, and fields within records, can have dependent types. Updates
1019Records, and fields within records, can have dependent types. Updates
1018are allowed to change the type of a field, provided that the result is
1020are allowed to change the type of a field, provided that the result is
1019−well-typed, and the result does not affect the type of the record as a
1021+well-typed.
1020−whole. For example:
1021
1022
1022.. code-block:: idris
1023.. code-block:: idris
1023
1024
1024− record Class : Type where
1025+ record Class where
1026+ constructor ClassInfo
1025− ClassInfo : (students : Vect n Person) ->
1027+ students : Vect n Person
1026− (className : String) ->
1028+ className : String
1027− Class
1028
1029
1029It is safe to update the ``students`` field to a vector of a different
1030It is safe to update the ``students`` field to a vector of a different
1030length because it will not affect the type of the record:
1031length because it will not affect the type of the record:
@@ -1037,8 +1038,7 @@ length because it will not affect the type of the record:
1037::
1038::
1038
1039
1039 *record> addStudent fred (ClassInfo [] "CS")
1040 *record> addStudent fred (ClassInfo [] "CS")
1040− ClassInfo (prelude.vect.:: (MkPerson "Fred" 30) (prelude.vect.Nil)) "CS"
1041+ ClassInfo [MkPerson "Fred" 30] "CS" : Class
1041− : Class
1042
1042
1043Nested record update
1043Nested record update
1044--------------------
1044--------------------
@@ -1060,3 +1060,32 @@ can also be accessed with the following syntax:
1060.. code-block:: idris
1060.. code-block:: idris
1061
1061
1062 record { a->b->c } x
1062 record { a->b->c } x
1063+
1064+Parameters and Fields
1065+---------------------
1066+
1067+Records can have *parameters*, which are not subject to field
1068+updates. The parameters appear as arguments to the resulting type, and
1069+are written following the record type name. For example, a pair type
1070+could be defined as follows:
1071+
1072+.. code-block:: idris
1073+
1074+ record Prod a b where
1075+ constructor Times
1076+ fst : a
1077+ snd : b
1078+
1079+The parameters to a record type need not be types. For example, we can
1080+restrict the size of classes using a ``Nat`` parameter to the
1081+``Class`` record:
1082+
1083+.. code-block:: idris
1084+
1085+ record SizedClass (size : Nat) where
1086+ constructor SizedClassInfo
1087+ students : Vect size Person
1088+ className : String
1089+
1090+Note that it is no longer possible to write ``addStudent`` for this
1091+type, as that would change the size of the class.
idris.cabal+7
@@ -357,6 +357,13 @@ Extra-source-files:
357 test/bignum002/*.idr
357 test/bignum002/*.idr
358 test/bignum002/expected
358 test/bignum002/expected
359
359
360+ test/corecords001/*.idr
361+ test/corecords001/run
362+ test/corecords001/expected
363+ test/corecords002/*.idr
364+ test/corecords002/run
365+ test/corecords002/expected
366+
360 test/delab001/*.idr
367 test/delab001/*.idr
361 test/delab001/run
368 test/delab001/run
362 test/delab001/expected
369 test/delab001/expected
libs/base/Control/Monad/Identity.idr+3−2
@@ -1,7 +1,8 @@
1module Control.Monad.Identity
1module Control.Monad.Identity
2
2
3−public record Identity : Type -> Type where
3+public record Identity (a : Type) where
4+ constructor Id
4− Id : (runIdentity : a) -> Identity a
5+ runIdentity : a
5
6
6instance Functor Identity where
7instance Functor Identity where
7 map fn (Id a) = Id (fn a)
8 map fn (Id a) = Id (fn a)
libs/base/Control/Monad/RWS.idr+4−4
@@ -11,10 +11,10 @@ import Control.Monad.Reader
11class (Monoid w, MonadReader r m, MonadWriter w m, MonadState s m) => MonadRWS r w s (m : Type -> Type) where {}
11class (Monoid w, MonadReader r m, MonadWriter w m, MonadState s m) => MonadRWS r w s (m : Type -> Type) where {}
12
12
13||| The transformer on which the RWS monad is based
13||| The transformer on which the RWS monad is based
14−record RWST : Type -> Type -> Type -> (Type -> Type) -> Type -> Type where
14+record RWST (r : Type) (w : Type) (s : Type) (m : Type -> Type) (a : Type) where
15− MkRWST : {m : Type -> Type} ->
15+ constructor MkRWST
16− (runRWST : r -> s -> m (a, s, w)) -> RWST r w s m a
16+ runRWST : r -> s -> m (a, s, w)
17−
17+
18instance Monad m => Functor (RWST r w s m) where
18instance Monad m => Functor (RWST r w s m) where
19 map f (MkRWST m) = MkRWST $ \r,s => do (a, s', w) <- m r s
19 map f (MkRWST m) = MkRWST $ \r,s => do (a, s', w) <- m r s
20 return (f a, s', w)
20 return (f a, s', w)
libs/base/Control/Monad/Reader.idr+3−3
@@ -14,9 +14,9 @@ class Monad m => MonadReader r (m : Type -> Type) where
14 local : (r -> r) -> m a -> m a
14 local : (r -> r) -> m a -> m a
15
15
16||| The transformer on which the Reader monad is based
16||| The transformer on which the Reader monad is based
17−record ReaderT : Type -> (Type -> Type) -> Type -> Type where
17+record ReaderT (r : Type) (m : Type -> Type) (a : Type) where
18− RD : {m : Type -> Type} ->
18+ constructor RD
19− (runReaderT : r -> m a) -> ReaderT r m a
19+ runReaderT : r -> m a
20
20
21||| Create a ReaderT with an empty context
21||| Create a ReaderT with an empty context
22liftReaderT : {m : Type -> Type} -> m a -> ReaderT r m a
22liftReaderT : {m : Type -> Type} -> m a -> ReaderT r m a
libs/base/Control/Monad/State.idr+5−5
@@ -13,9 +13,9 @@ class Monad m => MonadState s (m : Type -> Type) | m where
13 put : s -> m ()
13 put : s -> m ()
14
14
15||| The transformer on which the State monad is based
15||| The transformer on which the State monad is based
16−record StateT : Type -> (Type -> Type) -> Type -> Type where
16+record StateT (s : Type) (m : Type -> Type) (a : Type) where
17− ST : {m : Type -> Type} ->
17+ constructor ST
18− (runStateT : s -> m (a, s)) -> StateT s m a
18+ runStateT : s -> m (a, s)
19
19
20instance Functor f => Functor (StateT s f) where
20instance Functor f => Functor (StateT s f) where
21 map f (ST g) = ST (\st => map (mapFst f) (g st)) where
21 map f (ST g) = ST (\st => map (mapFst f) (g st)) where
@@ -57,8 +57,8 @@ State : Type -> Type -> Type
57State s a = StateT s Identity a
57State s a = StateT s Identity a
58
58
59||| Unwrap a State monad computation.
59||| Unwrap a State monad computation.
60−runState : State s a -> s -> (a,s)
60+runState : StateT s Identity a -> s -> (a, s)
61−runState m = runIdentity . runStateT m
61+runState act = runIdentity . runStateT act
62
62
63||| Unwrap a State monad computation, but discard the final state.
63||| Unwrap a State monad computation, but discard the final state.
64evalState : State s a -> s -> a
64evalState : State s a -> s -> a
libs/base/Control/Monad/Writer.idr+3−3
@@ -16,9 +16,9 @@ class (Monoid w, Monad m) => MonadWriter w (m : Type -> Type) where
16 pass : m (a, w -> w) -> m a
16 pass : m (a, w -> w) -> m a
17
17
18||| The transformer base of the Writer monad
18||| The transformer base of the Writer monad
19−record WriterT : Type -> (Type -> Type) -> Type -> Type where
19+record WriterT (w : Type) (m : Type -> Type) (a : Type) where
20− WR : {m : Type -> Type} ->
20+ constructor WR
21− (runWriterT : m (a, w)) -> WriterT w m a
21+ runWriterT : m (a, w)
22
22
23instance Functor f => Functor (WriterT w f) where
23instance Functor f => Functor (WriterT w f) where
24 map f (WR g) = WR $ map (\w => (f . fst $ w, snd w)) g
24 map f (WR g) = WR $ map (\w => (f . fst $ w, snd w)) g
libs/contrib/Network/Cgi.idr+8−7
@@ -8,13 +8,14 @@ public
8Vars : Type
8Vars : Type
9Vars = List (String, String)
9Vars = List (String, String)
10
10
11−record CGIInfo : Type where
11+record CGIInfo where
12+ constructor CGISt
12− CGISt : (GET : Vars) ->
13+ GET : Vars
13− (POST : Vars) ->
14+ POST : Vars
14− (Cookies : Vars) ->
15+ Cookies : Vars
15− (UserAgent : String) ->
16+ UserAgent : String
16− (Headers : String) ->
17+ Headers : String
17− (Output : String) -> CGIInfo
18+ Output : String
18
19
19add_Headers : String -> CGIInfo -> CGIInfo
20add_Headers : String -> CGIInfo -> CGIInfo
20add_Headers str st = record { Headers = Headers st ++ str } st
21add_Headers str st = record { Headers = Headers st ++ str } st
libs/contrib/Network/Socket.idr+17−19
@@ -107,19 +107,17 @@ EAGAIN : Int
107EAGAIN = 11
107EAGAIN = 11
108
108
109-- TODO: Expand to non-string payloads
109-- TODO: Expand to non-string payloads
110−record UDPRecvData : Type where
110+record UDPRecvData where
111− MkUDPRecvData :
111+ constructor MkUDPRecvData
112− (remote_addr : SocketAddress) ->
112+ remote_addr : SocketAddress
113− (remote_port : Port) ->
113+ remote_port : Port
114− (recv_data : String) ->
114+ recv_data : String
115− (data_len : Int) ->
115+ data_len : Int
116− UDPRecvData
116+
117−
118−record UDPAddrInfo : Type where
117+record UDPAddrInfo where
119− MkUDPAddrInfo :
118+ constructor MkUDPAddrInfo
120− (remote_addr : SocketAddress) ->
119+ remote_addr : SocketAddress
121− (remote_port : Port) ->
120+ remote_port : Port
122− UDPAddrInfo
123
121
124||| Frees a given pointer
122||| Frees a given pointer
125public
123public
@@ -138,12 +136,12 @@ sock_alloc : ByteLength -> IO BufPtr
138sock_alloc bl = map BPtr $ foreign FFI_C "idrnet_malloc" (Int -> IO Ptr) bl
136sock_alloc bl = map BPtr $ foreign FFI_C "idrnet_malloc" (Int -> IO Ptr) bl
139
137
140||| The metadata about a socket
138||| The metadata about a socket
141−record Socket : Type where
139+record Socket where
140+ constructor MkSocket
142− MkSocket : (descriptor : SocketDescriptor) ->
141+ descriptor : SocketDescriptor
143− (family : SocketFamily) ->
142+ family : SocketFamily
144− (socketType : SocketType) ->
143+ socketType : SocketType
145− (protocolNumber : ProtocolNumber) ->
144+ protocalNumber : ProtocolNumber
146− Socket
147
145
148||| Get the C error number
146||| Get the C error number
149getErrno : IO Int
147getErrno : IO Int
libs/prelude/IO.idr+5−4
@@ -20,10 +20,11 @@ world (TheWorld w) = w
20abstract WorldRes : Type -> Type
20abstract WorldRes : Type -> Type
21WorldRes x = x
21WorldRes x = x
22
22
23−record FFI : Type where
23+record FFI where
24+ constructor MkFFI
24− MkFFI : (ffi_types : Type -> Type) ->
25+ ffi_types : Type -> Type
25− (ffi_fn : Type) ->
26+ ffi_fn : Type
26− (ffi_data : Type) -> FFI
27+ ffi_data : Type
27
28
28abstract
29abstract
29data IO' : (lang : FFI) -> Type -> Type where
30data IO' : (lang : FFI) -> Type -> Type where
libs/prelude/Prelude/Nat.idr+7−5
@@ -214,13 +214,15 @@ instance Cast Integer Nat where
214 cast = fromInteger
214 cast = fromInteger
215
215
216||| A wrapper for Nat that specifies the semigroup and monad instances that use (+)
216||| A wrapper for Nat that specifies the semigroup and monad instances that use (+)
217−record Multiplicative : Type where
217+record Multiplicative where
218− getMultiplicative : Nat -> Multiplicative
218+ constructor getMultiplicative
219+ _ : Nat
219
220
220||| A wrapper for Nat that specifies the semigroup and monad instances that use (*)
221||| A wrapper for Nat that specifies the semigroup and monad instances that use (*)
221−record Additive : Type where
222+record Additive where
222− getAdditive : Nat -> Additive
223+ constructor getAdditive
223−
224+ _ : Nat
225+
224instance Semigroup Multiplicative where
226instance Semigroup Multiplicative where
225 (<+>) left right = getMultiplicative $ left' * right'
227 (<+>) left right = getMultiplicative $ left' * right'
226 where
228 where
src/Idris/AbsSyntax.hs+2−7
@@ -1093,13 +1093,8 @@ expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
1093 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
1093 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
1094 econ (doc, argDocs, n, t, fc, fs)
1094 econ (doc, argDocs, n, t, fc, fs)
1095 = (doc, argDocs, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
1095 = (doc, argDocs, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
1096−expandParamsD rhs ist dec ps ns (PRecord doc syn fc tn tty opts cdoc cn cty)
1096+expandParamsD rhs ist dec ps ns d@(PRecord doc rsyn fc opts name prs pdocs fls cn cdoc csyn)
1097− = if tn `elem` ns
1097+ = d
1098− then PRecord doc syn fc (dec tn) (piBind ps (expandParams dec ps ns [] tty))
1099− opts cdoc (dec cn) conty
1100− else PRecord doc syn fc (dec tn) (expandParams dec ps ns [] tty)
1101− opts cdoc (dec cn) conty
1102− where conty = piBindp expl ps (expandParams dec ps ns [] cty)
1103expandParamsD rhs ist dec ps ns (PParams f params pds)
1098expandParamsD rhs ist dec ps ns (PParams f params pds)
1104 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1099 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
1105 (map (expandParamsD True ist dec ps ns) pds)
1100 (map (expandParamsD True ist dec ps ns) pds)
src/Idris/AbsSyntaxTree.hs+15−7
@@ -36,7 +36,7 @@ import qualified Data.Text as T
36import Data.Either
36import Data.Either
37import qualified Data.Set as S
37import qualified Data.Set as S
38import Data.Word (Word)
38import Data.Word (Word)
39−import Data.Maybe (fromMaybe, mapMaybe)
39+import Data.Maybe (fromMaybe, mapMaybe, maybeToList)
40import Data.Traversable (Traversable)
40import Data.Traversable (Traversable)
41import Data.Typeable
41import Data.Typeable
42import Data.Foldable (Foldable)
42import Data.Foldable (Foldable)
@@ -582,7 +582,6 @@ dictionary :: FnOpts -> Bool
582dictionary = elem Dictionary
582dictionary = elem Dictionary
583
583
584
584
585−
586-- | Type provider - what to provide
585-- | Type provider - what to provide
587data ProvideWhat' t = ProvTerm t t -- ^ the first is the goal type, the second is the term
586data ProvideWhat' t = ProvTerm t t -- ^ the first is the goal type, the second is the term
588 | ProvPostulate t -- ^ goal type must be Type, so only term
587 | ProvPostulate t -- ^ goal type must be Type, so only term
@@ -602,7 +601,15 @@ data PDecl' t
602 | PData (Docstring (Either Err PTerm)) [(Name, Docstring (Either Err PTerm))] SyntaxInfo FC DataOpts (PData' t) -- ^ Data declaration.
601 | PData (Docstring (Either Err PTerm)) [(Name, Docstring (Either Err PTerm))] SyntaxInfo FC DataOpts (PData' t) -- ^ Data declaration.
603 | PParams FC [(Name, t)] [PDecl' t] -- ^ Params block
602 | PParams FC [(Name, t)] [PDecl' t] -- ^ Params block
604 | PNamespace String [PDecl' t] -- ^ New namespace
603 | PNamespace String [PDecl' t] -- ^ New namespace
605− | PRecord (Docstring (Either Err PTerm)) SyntaxInfo FC Name t DataOpts (Docstring (Either Err PTerm)) Name t -- ^ Record declaration
604+ | PRecord (Docstring (Either Err PTerm)) SyntaxInfo FC DataOpts
605+ Name -- Record name
606+ [(Name, Plicity, t)] -- Parameters
607+ [(Name, Docstring (Either Err PTerm))] -- Param Docs
608+ [((Maybe Name), Plicity, t, Maybe (Docstring (Either Err PTerm)))] -- Fields
609+ (Maybe Name) -- Optional constructor name
610+ (Docstring (Either Err PTerm)) -- Constructor doc
611+ SyntaxInfo -- Constructor SyntaxInfo
612+ -- ^ Record declaration
606 | PClass (Docstring (Either Err PTerm)) SyntaxInfo FC
613 | PClass (Docstring (Either Err PTerm)) SyntaxInfo FC
607 [(Name, t)] -- constraints
614 [(Name, t)] -- constraints
608 Name
615 Name
@@ -725,13 +732,14 @@ declared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
725declared (PData _ _ _ _ _ (PLaterdecl n _)) = [n]
732declared (PData _ _ _ _ _ (PLaterdecl n _)) = [n]
726declared (PParams _ _ ds) = concatMap declared ds
733declared (PParams _ _ ds) = concatMap declared ds
727declared (PNamespace _ ds) = concatMap declared ds
734declared (PNamespace _ ds) = concatMap declared ds
728−declared (PRecord _ _ _ n _ _ _ c _) = [n, c]
735+declared (PRecord _ _ _ _ n _ _ _ cn _ _) = n : maybeToList cn
729declared (PClass _ _ _ _ n _ _ _ ms) = n : concatMap declared ms
736declared (PClass _ _ _ _ n _ _ _ ms) = n : concatMap declared ms
730declared (PInstance _ _ _ _ _ _ _ _ _ _) = []
737declared (PInstance _ _ _ _ _ _ _ _ _ _) = []
731declared (PDSL n _) = [n]
738declared (PDSL n _) = [n]
732declared (PSyntax _ _) = []
739declared (PSyntax _ _) = []
733declared (PMutual _ ds) = concatMap declared ds
740declared (PMutual _ ds) = concatMap declared ds
734declared (PDirective _) = []
741declared (PDirective _) = []
742+declared _ = []
735
743
736-- get the names declared, not counting nested parameter blocks
744-- get the names declared, not counting nested parameter blocks
737tldeclared :: PDecl -> [Name]
745tldeclared :: PDecl -> [Name]
@@ -739,7 +747,7 @@ tldeclared (PFix _ _ _) = []
739tldeclared (PTy _ _ _ _ _ n t) = [n]
747tldeclared (PTy _ _ _ _ _ n t) = [n]
740tldeclared (PPostulate _ _ _ _ _ n t) = [n]
748tldeclared (PPostulate _ _ _ _ _ n t) = [n]
741tldeclared (PClauses _ _ n _) = [] -- not a declaration
749tldeclared (PClauses _ _ n _) = [] -- not a declaration
742−tldeclared (PRecord _ _ _ n _ _ _ c _) = [n, c]
750+tldeclared (PRecord _ _ _ _ n _ _ _ cn _ _) = n : maybeToList cn
743tldeclared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
751tldeclared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
744 where fstt (_, _, a, _, _, _) = a
752 where fstt (_, _, a, _, _, _) = a
745tldeclared (PParams _ _ ds) = []
753tldeclared (PParams _ _ ds) = []
@@ -760,14 +768,14 @@ defined (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
760defined (PData _ _ _ _ _ (PLaterdecl n _)) = []
768defined (PData _ _ _ _ _ (PLaterdecl n _)) = []
761defined (PParams _ _ ds) = concatMap defined ds
769defined (PParams _ _ ds) = concatMap defined ds
762defined (PNamespace _ ds) = concatMap defined ds
770defined (PNamespace _ ds) = concatMap defined ds
763−defined (PRecord _ _ _ n _ _ _ c _) = [n, c]
771+defined (PRecord _ _ _ _ n _ _ _ cn _ _) = n : maybeToList cn
764defined (PClass _ _ _ _ n _ _ _ ms) = n : concatMap defined ms
772defined (PClass _ _ _ _ n _ _ _ ms) = n : concatMap defined ms
765defined (PInstance _ _ _ _ _ _ _ _ _ _) = []
773defined (PInstance _ _ _ _ _ _ _ _ _ _) = []
766defined (PDSL n _) = [n]
774defined (PDSL n _) = [n]
767defined (PSyntax _ _) = []
775defined (PSyntax _ _) = []
768defined (PMutual _ ds) = concatMap defined ds
776defined (PMutual _ ds) = concatMap defined ds
769defined (PDirective _) = []
777defined (PDirective _) = []
770−--defined _ = []
778+defined _ = []
771
779
772updateN :: [(Name, Name)] -> Name -> Name
780updateN :: [(Name, Name)] -> Name -> Name
773updateN ns n | Just n' <- lookup n ns = n'
781updateN ns n | Just n' <- lookup n ns = n'
src/Idris/DeepSeq.hs+2−2
@@ -145,11 +145,11 @@ instance (NFData t) => NFData (PDecl' t) where
145 rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
145 rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
146 rnf (PParams x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
146 rnf (PParams x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
147 rnf (PNamespace x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
147 rnf (PNamespace x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
148− rnf (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9)
148+ rnf (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11)
149 = rnf x1 `seq`
149 = rnf x1 `seq`
150 rnf x2 `seq`
150 rnf x2 `seq`
151 rnf x3 `seq`
151 rnf x3 `seq`
152− rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` rnf x9 `seq` ()
152+ rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` rnf x9 `seq` rnf x10 `seq` rnf x11 `seq` ()
153 rnf (PClass x1 x2 x3 x4 x5 x6 x8 x7 x9)
153 rnf (PClass x1 x2 x3 x4 x5 x6 x8 x7 x9)
154 = rnf x1 `seq`
154 = rnf x1 `seq`
155 rnf x2 `seq`
155 rnf x2 `seq`
src/Idris/Elab/Record.hs+414−211
@@ -1,9 +1,8 @@
1−{-# LANGUAGE PatternGuards #-}
1+{-# LANGUAGE PatternGuards, ViewPatterns #-}
2module Idris.Elab.Record(elabRecord) where
2module Idris.Elab.Record(elabRecord) where
3
3
4import Idris.AbsSyntax
4import Idris.AbsSyntax
5−import Idris.ASTUtils
5+import Idris.Docstrings
6−import Idris.DSL
7import Idris.Error
6import Idris.Error
8import Idris.Delaborate
7import Idris.Delaborate
9import Idris.Imports
8import Idris.Imports
@@ -18,225 +17,429 @@ import Idris.DeepSeq
18import Idris.Output (iputStrLn, pshow, iWarn)
17import Idris.Output (iputStrLn, pshow, iWarn)
19import IRTS.Lang
18import IRTS.Lang
20
19
20+import Idris.ParseExpr (tryFullExpr)
21+
21import Idris.Elab.Type
22import Idris.Elab.Type
22import Idris.Elab.Data
23import Idris.Elab.Data
23import Idris.Elab.Utils
24import Idris.Elab.Utils
24
25
25import Idris.Core.TT
26import Idris.Core.TT
26−import Idris.Core.Elaborate hiding (Tactic(..))
27import Idris.Core.Evaluate
27import Idris.Core.Evaluate
28−import Idris.Core.Execute
29−import Idris.Core.Typecheck
30−import Idris.Core.CaseTree
31−
32−import Idris.Docstrings
33
28
34−import Prelude hiding (id, (.))
29+import Idris.Elab.Data
35−import Control.Category
36
30
37−import Control.Applicative hiding (Const)
38−import Control.DeepSeq
39−import Control.Monad
40−import Control.Monad.State.Strict as State
41−import Data.List
42import Data.Maybe
31import Data.Maybe
43−import Debug.Trace
32+import Data.List
44−
33+import Control.Monad
45−import qualified Data.Map as Map
46−import qualified Data.Set as S
47−import qualified Data.Text as T
48−import Data.Char(isLetter, toLower)
49−import Data.List.Split (splitOn)
50−
51−import Util.Pretty(pretty, text)
52−
53−elabRecord :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) -> FC -> Name ->
54− PTerm -> DataOpts -> Docstring (Either Err PTerm) -> Name -> PTerm -> Idris ()
55−elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
56− = do elabData info syn doc [] fc opts (PDatadecl tyn ty [(cdoc, [], cn, cty_in, fc, [])])
57− -- TODO think: something more in info?
58− cty' <- implicit info syn cn cty_in
59− i <- getIState
60−
61− -- get bound implicits and propagate to setters (in case they
62− -- provide useful information for inference)
63− let extraImpls = getBoundImpls cty'
64−
65− cty <- case lookupTy cn (tt_ctxt i) of
66− [t] -> return (delab i t)
67− _ -> ifail "Something went inexplicably wrong"
68− cimp <- case lookupCtxt cn (idris_implicits i) of
69− [imps] -> return imps
70− ppos <- case lookupCtxt tyn (idris_datatypes i) of
71− [ti] -> return $ param_pos ti
72− let cty_imp = renameBs cimp cty
73− let ptys = getProjs [] cty_imp
74− let ptys_u = getProjs [] cty
75− let recty = getRecTy cty_imp
76− let recty_u = getRecTy cty
77−
78− let paramNames = getPNames recty ppos
79−
80− -- rename indices when we generate the getter/setter types, so
81− -- that they don't clash with the names of the projections
82− -- we're generating
83− let index_names_in = getRecNameMap "_in" ppos recty
84− let recty_in = substMatches index_names_in recty
85−
86− logLvl 3 $ show (recty, recty_u, ppos, paramNames, ptys)
87− -- Substitute indices with projection functions, and parameters with
88− -- the updated parameter name
89− let substs = map (\ (n, _) ->
90− if n `elem` paramNames
91− then (n, PRef fc (mkp n))
92− else (n, PApp fc (PRef fc n)
93− [pexp (PRef fc rec)]))
94− ptys
95−
96− -- Generate projection functions
97− proj_decls <- mapM (mkProj recty_in substs cimp) (zip ptys [0..])
98− logLvl 3 $ show proj_decls
99− let nonImp = mapMaybe isNonImp (zip cimp ptys_u)
100− let implBinds = getImplB id cty'
101−
102− -- Generate update functions
103− update_decls <- mapM (mkUpdate recty_u index_names_in extraImpls
104− (getFieldNames cty')
105− implBinds (length nonImp)) (zip nonImp [0..])
106− mapM_ (rec_elabDecl info EAll info) (concat proj_decls)
107− logLvl 3 $ show update_decls
108− mapM_ (tryElabDecl info) (update_decls)
109− where
110−-- syn = syn_in { syn_namespace = show (nsroot tyn) : syn_namespace syn_in }
111
34
112− isNonImp (PExp _ _ _ _, a) = Just a
35+-- | Elaborate a record declaration
113− isNonImp _ = Nothing
36+elabRecord :: ElabInfo
37+ -> (Docstring (Either Err PTerm)) -- ^ The documentation for the whole declaration
38+ -> SyntaxInfo -> FC -> DataOpts
39+ -> Name -- ^ The name of the type being defined
40+ -> [(Name, Plicity, PTerm)] -- ^ Parameters
41+ -> [(Name, Docstring (Either Err PTerm))] -- ^ Parameter Docs
42+ -> [((Maybe Name), Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))] -- ^ Fields
43+ -> Maybe Name -- ^ Constructor Name
44+ -> (Docstring (Either Err PTerm)) -- ^ Constructor Doc
45+ -> SyntaxInfo -- ^ Constructor SyntaxInfo
46+ -> Idris ()
47+elabRecord info doc rsyn fc opts tyn params paramDocs fields cname cdoc csyn
48+ = do logLvl 1 $ "Building data declaration for " ++ show tyn
49+ -- Type constructor
50+ let tycon = generateTyConType params
51+ logLvl 1 $ "Type constructor " ++ showTmImpls tycon
52+
53+ -- Data constructor
54+ dconName <- generateDConName cname
55+ let dconTy = generateDConType params fieldsWithNameAndDoc
56+ logLvl 1 $ "Data constructor: " ++ showTmImpls dconTy
57+
58+ -- Build data declaration for elaboration
59+ iLOG $ foldr (++) "" $ intersperse "\n" (map show dconsArgDocs)
60+ let datadecl = PDatadecl tyn tycon [(cdoc, dconsArgDocs, dconName, dconTy, fc, [])]
61+ elabData info rsyn doc paramDocs fc opts datadecl
62+
63+ iLOG $ "fieldsWithName " ++ show fieldsWithName
64+ iLOG $ "fieldsWIthNameAndDoc " ++ show fieldsWithNameAndDoc
65+ elabRecordFunctions info rsyn fc tyn paramsAndDoc fieldsWithNameAndDoc dconName target
66+ where
67+ -- | Generates a type constructor.
68+ generateTyConType :: [(Name, Plicity, PTerm)] -> PTerm
69+ generateTyConType ((n, p, t) : rest) = PPi p (nsroot n) t (generateTyConType rest)
70+ generateTyConType [] = PType
71+
72+ -- | Generates a name for the data constructor if none was specified.
73+ generateDConName :: Maybe Name -> Idris Name
74+ generateDConName (Just n) = return $ expandNS csyn n
75+ generateDConName Nothing = uniqueName (expandNS csyn $ sMN 0 ("Mk" ++ (show (nsroot tyn))))
76+ where
77+ uniqueName :: Name -> Idris Name
78+ uniqueName n = do i <- getIState
79+ case lookupTyNameExact n (tt_ctxt i) of
80+ Just _ -> uniqueName (nextName n)
81+ Nothing -> return n
82+
83+ -- | Generates the data constructor type.
84+ generateDConType :: [(Name, Plicity, PTerm)] -> [(Name, Plicity, PTerm, a)] -> PTerm
85+ generateDConType ((n, _, t) : ps) as = PPi impl (nsroot n) t (generateDConType ps as)
86+ generateDConType [] ((n, p, t, _) : as) = PPi p (nsroot n) t (generateDConType [] as)
87+ generateDConType [] [] = target
88+
89+ -- | The target for the constructor and projection functions. Also the source of the update functions.
90+ target :: PTerm
91+ target = PApp fc (PRef fc tyn) $ map (uncurry asPRefArg) [(p, n) | (n, p, _) <- params]
92+
93+ paramsAndDoc :: [(Name, Plicity, PTerm, Docstring (Either Err PTerm))]
94+ paramsAndDoc = pad params paramDocs
95+ where
96+ pad :: [(Name, Plicity, PTerm)] -> [(Name, Docstring (Either Err PTerm))] -> [(Name, Plicity, PTerm, Docstring (Either Err PTerm))]
97+ pad ((n, p, t) : rest) docs
98+ = let d = case lookup n docs of
99+ Just d' -> d
100+ Nothing -> emptyDocstring
101+ in (n, p, t, d) : (pad rest docs)
102+ pad _ _ = []
103+
104+ dconsArgDocs :: [(Name, Docstring (Either Err PTerm))]
105+ dconsArgDocs = paramDocs ++ (dcad fieldsWithName)
106+ where
107+ dcad :: [(Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))] -> [(Name, Docstring (Either Err PTerm))]
108+ dcad ((n, _, _, (Just d)) : rest) = ((nsroot n), d) : (dcad rest)
109+ dcad (_ : rest) = dcad rest
110+ dcad [] = []
114
111
115− getPNames (PApp _ _ as) ppos = getpn as ppos
112+ fieldsWithName :: [(Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))]
113+ fieldsWithName = fwn [] fields
114+ where
115+ fwn :: [Name] -> [(Maybe Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))] -> [(Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))]
116+ fwn ns ((n, p, t, d) : rest)
117+ = let nn = case n of
118+ Just n' -> n'
119+ Nothing -> newName ns baseName
120+ in (expandNS rsyn $ nn, p, t, d) : (fwn (nn : ns) rest)
121+ fwn _ _ = []
122+
123+ baseName = sUN "__pi_arg"
124+
125+ newName :: [Name] -> Name -> Name
126+ newName ns n
127+ | n `elem` ns = newName ns (nextName n)
128+ | otherwise = n
129+
130+ fieldsWithNameAndDoc :: [(Name, Plicity, PTerm, Docstring (Either Err PTerm))]
131+ fieldsWithNameAndDoc = fwnad fieldsWithName
132+ where
133+ fwnad :: [(Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))] -> [(Name, Plicity, PTerm, Docstring (Either Err PTerm))]
134+ fwnad ((n, p, t, d) : rest)
135+ = let doc = fromMaybe emptyDocstring d
136+ in (n, p, t, doc) : (fwnad rest)
137+ fwnad [] = []
138+
139+elabRecordFunctions :: ElabInfo -> SyntaxInfo -> FC
140+ -> Name -- ^ Record type name
141+ -> [(Name, Plicity, PTerm, Docstring (Either Err PTerm))] -- ^ Parameters
142+ -> [(Name, Plicity, PTerm, Docstring (Either Err PTerm))] -- ^ Fields
143+ -> Name -- ^ Constructor Name
144+ -> PTerm -- ^ Target type
145+ -> Idris ()
146+elabRecordFunctions info rsyn fc tyn params fields dconName target
147+ = do logLvl 1 $ "Elaborating helper functions for record " ++ show tyn
148+
149+ iLOG $ "Fields: " ++ show fieldNames
150+ iLOG $ "Params: " ++ show paramNames
151+ -- The elaborated constructor type for the data declaration
152+ i <- getIState
153+ ttConsTy <-
154+ case lookupTyExact dconName (tt_ctxt i) of
155+ Just as -> return as
156+ Nothing -> tclift $ tfail $ At fc (Elaborating "record " tyn (InternalMsg "It seems like the constructor for this record has disappeared. :( \n This is a bug. Please report."))
157+
158+ -- The arguments to the constructor
159+ let constructorArgs = getArgTys ttConsTy
160+ iLOG $ "Cons args: " ++ show constructorArgs
161+ iLOG $ "Free fields: " ++ show (filter (not . isFieldOrParam') constructorArgs)
162+ -- If elaborating the constructor has resulted in some new implicit fields we make projection functions for them.
163+ let freeFieldsForElab = map (freeField i) (filter (not . isFieldOrParam') constructorArgs)
164+
165+ -- The parameters for elaboration with their documentation
166+ -- Parameter functions are all prefixed with "param_".
167+ let paramsForElab = [((nsroot n), (paramName n), impl, t, d) | (n, _, t, d) <- params] -- zipParams i params paramDocs]
168+
169+ -- The fields (written by the user) with their documentation.
170+ let userFieldsForElab = [((nsroot n), n, p, t, d) | (n, p, t, d) <- fields]
171+
172+ -- All things we need to elaborate projection functions for, together with a number denoting their position in the constructor.
173+ let projectors = [(n, n', p, t, d, i) | ((n, n', p, t, d), i) <- zip (freeFieldsForElab ++ paramsForElab ++ userFieldsForElab) [0..]]
174+ -- Build and elaborate projection functions
175+ elabProj dconName projectors
176+
177+ logLvl 1 $ "Dependencies: " ++ show fieldDependencies
178+
179+ logLvl 1 $ "Depended on: " ++ show dependedOn
180+
181+ -- All things we need to elaborate update functions for, together with a number denoting their position in the constructor.
182+ let updaters = [(n, n', p, t, d, i) | ((n, n', p, t, d), i) <- zip (paramsForElab ++ userFieldsForElab) [0..]]
183+ -- Build and elaborate update functions
184+ elabUp dconName updaters
185+ where
186+ -- | Creates a PArg from a plicity and a name where the term is a Placeholder.
187+ placeholderArg :: Plicity -> Name -> PArg
188+ placeholderArg p n = asArg p (nsroot n) Placeholder
189+
190+ -- | Root names of all fields in the current record declarations
191+ fieldNames :: [Name]
192+ fieldNames = [nsroot n | (n, _, _, _) <- fields]
193+
194+ paramNames :: [Name]
195+ paramNames = [nsroot n | (n, _, _, _) <- params]
196+
197+ isFieldOrParam :: Name -> Bool
198+ isFieldOrParam n = n `elem` (fieldNames ++ paramNames)
199+
200+ isFieldOrParam' :: (Name, a) -> Bool
201+ isFieldOrParam' = isFieldOrParam . fst
202+
203+ isField :: Name -> Bool
204+ isField = flip elem fieldNames
205+
206+ isField' :: (Name, a, b, c, d, f) -> Bool
207+ isField' (n, _, _, _, _, _) = isField n
208+
209+ fieldTerms :: [PTerm]
210+ fieldTerms = [t | (_, _, t, _) <- fields]
211+
212+ -- Delabs the TT to PTerm
213+ -- This is not good.
214+ -- However, for machine generated implicits, there seems to be no PTerm available.
215+ -- Is there a better way to do this without building the setters and getters as TT?
216+ freeField :: IState -> (Name, TT Name) -> (Name, Name, Plicity, PTerm, Docstring (Either Err PTerm))
217+ freeField i arg = let nameInCons = fst arg -- The name as it appears in the constructor
218+ nameFree = expandNS rsyn (freeName $ fst arg) -- The name prefixed with "free_"
219+ plicity = impl -- All free fields are implicit as they are machine generated
220+ fieldType = delab i (snd arg) -- The type of the field
221+ doc = emptyDocstring -- No docmentation for machine generated fields
222+ in (nameInCons, nameFree, plicity, fieldType, doc)
223+
224+ freeName :: Name -> Name
225+ freeName (UN n) = sUN ("free_" ++ str n)
226+ freeName (MN i n) = sMN i ("free_" ++ str n)
227+ freeName (NS n s) = NS (freeName n) s
228+ freeName n = n
229+
230+ -- | Zips together parameters with their documentation. If no documentation for a given field exists, an empty docstring is used.
231+ zipParams :: IState -> [(Name, Plicity, PTerm)] -> [(Name, Docstring (Either Err PTerm))] -> [(Name, PTerm, Docstring (Either Err PTerm))]
232+ zipParams i ((n, _, t) : rest) ((_, d) : rest') = (n, t, d) : (zipParams i rest rest')
233+ zipParams i ((n, _, t) : rest) [] = (n, t, emptyDoc) : (zipParams i rest [])
234+ where emptyDoc = annotCode (tryFullExpr rsyn i) emptyDocstring
235+ zipParams _ [] [] = []
236+
237+ paramName :: Name -> Name
238+ paramName (UN n) = sUN ("param_" ++ str n)
239+ paramName (MN i n) = sMN i ("param_" ++ str n)
240+ paramName (NS n s) = NS (paramName n) s
241+ paramName n = n
242+
243+ -- | Elaborate the projection functions.
244+ elabProj :: Name -> [(Name, Name, Plicity, PTerm, Docstring (Either Err PTerm), Int)] -> Idris ()
245+ elabProj cn fs = let phArgs = map (uncurry placeholderArg) [(p, n) | (n, _, p, _, _, _) <- fs]
246+ elab = \(n, n', p, t, doc, i) ->
247+ -- Use projections in types
248+ do let t' = projectInType [(m, m') | (m, m', _, _, _, _) <- fs
249+ -- Parameters are already in scope, so just use them
250+ , not (m `elem` paramNames)] t
251+ elabProjection info n n' p t' doc rsyn fc target cn phArgs fieldNames i
252+ in mapM_ elab fs
253+
254+ -- | Elaborate the update functions.
255+ elabUp :: Name -> [(Name, Name, Plicity, PTerm, Docstring (Either Err PTerm), Int)] -> Idris ()
256+ elabUp cn fs = let args = map (uncurry asPRefArg) [(p, n) | (n, _, p, _, _, _) <- fs]
257+ elab = \(n, n', p, t, doc, i) -> elabUpdate info n n' p t doc rsyn fc target cn args fieldNames i (optionalSetter n)
258+ in mapM_ elab fs
259+
260+ -- | Decides whether a setter should be generated for a field or not.
261+ optionalSetter :: Name -> Bool
262+ optionalSetter n = n `elem` dependedOn
263+
264+ -- | A map from a field name to the other fields it depends on.
265+ fieldDependencies :: [(Name, [Name])]
266+ fieldDependencies = map (uncurry fieldDep) [(n, t) | (n, _, t, _) <- fields ++ params]
267+ where
268+ fieldDep :: Name -> PTerm -> (Name, [Name])
269+ fieldDep n t = ((nsroot n), paramNames ++ fieldNames `intersect` allNamesIn t)
270+
271+ -- | A list of fields depending on another field.
272+ dependentFields :: [Name]
273+ dependentFields = filter depends fieldNames
274+ where
275+ depends :: Name -> Bool
276+ depends n = case lookup n fieldDependencies of
277+ Just xs -> not $ null xs
278+ Nothing -> False
279+
280+ -- | A list of fields depended on by other fields.
281+ dependedOn :: [Name]
282+ dependedOn = concat ((catMaybes (map (\x -> lookup x fieldDependencies) fieldNames)))
283+
284+-- | Creates and elaborates a projection function.
285+elabProjection :: ElabInfo
286+ -> Name -- ^ Name of the argument in the constructor
287+ -> Name -- ^ Projection Name
288+ -> Plicity -- ^ Projection Plicity
289+ -> PTerm -- ^ Projection Type
290+ -> (Docstring (Either Err PTerm)) -- ^ Projection Documentation
291+ -> SyntaxInfo -- ^ Projection SyntaxInfo
292+ -> FC -> PTerm -- ^ Projection target type
293+ -> Name -- ^ Data constructor tame
294+ -> [PArg] -- ^ Placeholder Arguments to constructor
295+ -> [Name] -- ^ All Field Names
296+ -> Int -- ^ Argument Index
297+ -> Idris ()
298+elabProjection info cname pname plicity projTy pdoc psyn fc targetTy cn phArgs fnames index
299+ = do logLvl 1 $ "Generating Projection for " ++ show pname
300+
301+ let ty = generateTy
302+ logLvl 1 $ "Type of " ++ show pname ++ ": " ++ show ty
303+
304+ let lhs = generateLhs
305+ logLvl 1 $ "LHS of " ++ show pname ++ ": " ++ showTmImpls lhs
306+ let rhs = generateRhs
307+ logLvl 1 $ "RHS of " ++ show pname ++ ": " ++ showTmImpls rhs
308+
309+ rec_elabDecl info EAll info ty
310+
311+ let clause = PClause fc pname lhs [] rhs []
312+ rec_elabDecl info EAll info $ PClauses fc [] pname [clause]
313+ where
314+ -- | The type of the projection function.
315+ generateTy :: PDecl
316+ generateTy = PTy pdoc [] psyn fc [] pname $ PPi expl recName targetTy projTy
317+
318+ -- | The left hand side of the projection function.
319+ generateLhs :: PTerm
320+ generateLhs = let args = lhsArgs index phArgs
321+ in PApp fc (PRef fc pname) [pexp (PApp fc (PRef fc cn) args)]
116 where
322 where
117− getpn as [] = []
323+ lhsArgs :: Int -> [PArg] -> [PArg]
118− getpn as (i:is) | length as > i,
324+ lhsArgs 0 (_ : rest) = (asArg plicity (nsroot cname) (PRef fc pname_in)) : rest
119− PRef _ n <- getTm (as!!i) = n : getpn as is
325+ lhsArgs i (x : rest) = x : (lhsArgs (i-1) rest)
120− | otherwise = getpn as is
326+ lhsArgs _ [] = []
121− getPNames _ _ = []
327+
122−
328+ -- | The "_in" name. Used for the lhs.
123− tryElabDecl info (fn, ty, val)
329+ pname_in :: Name
124− = do i <- getIState
330+ pname_in = rootname -- in_name rootname
331+
332+ rootname :: Name
333+ rootname = nsroot cname
334+
335+ -- | The right hand side of the projection function.
336+ generateRhs :: PTerm
337+ generateRhs = PRef fc pname_in
338+
339+-- | Creates and elaborates an update function.
340+-- If 'optional' is true, we will not fail if we can't elaborate the update function.
341+elabUpdate :: ElabInfo
342+ -> Name -- ^ Name of the argument in the constructor
343+ -> Name -- ^ Field Name
344+ -> Plicity -- ^ Field Plicity
345+ -> PTerm -- ^ Field Type
346+ -> (Docstring (Either Err PTerm)) -- ^ Field Documentation
347+ -> SyntaxInfo -- ^ Field SyntaxInfo
348+ -> FC -> PTerm -- ^ Projection Source Type
349+ -> Name -- ^ Data Constructor Name
350+ -> [PArg] -- ^ Arguments to constructor
351+ -> [Name] -- ^ All fields
352+ -> Int -- ^ Argument Index
353+ -> Bool -- ^ Optional
354+ -> Idris ()
355+elabUpdate info cname pname plicity pty pdoc psyn fc sty cn args fnames i optional
356+ = do logLvl 1 $ "Generating Update for " ++ show pname
357+
358+ let ty = generateTy
359+ logLvl 1 $ "Type of " ++ show set_pname ++ ": " ++ show ty
360+
361+ let lhs = generateLhs
362+ logLvl 1 $ "LHS of " ++ show set_pname ++ ": " ++ showTmImpls lhs
363+
364+ let rhs = generateRhs
365+ logLvl 1 $ "RHS of " ++ show set_pname ++ ": " ++ showTmImpls rhs
366+
367+ let clause = PClause fc set_pname lhs [] rhs []
368+
125− idrisCatch (do rec_elabDecl info EAll info ty
369+ idrisCatch (do rec_elabDecl info EAll info ty
126− rec_elabDecl info EAll info val)
370+ rec_elabDecl info EAll info $ PClauses fc [] set_pname [clause])
127− (\v -> do iputStrLn $ show fc ++
371+ (\err -> logLvl 1 $ "Could not generate update function for " ++ show pname)
128− ":Warning - can't generate setter for " ++
372+ {-if optional
129− show fn ++ " (" ++ show ty ++ ")"
373+ then logLvl 1 $ "Could not generate update function for " ++ show pname
130−-- ++ "\n" ++ pshow i v
374+ else tclift $ tfail $ At fc (Elaborating "record update function " pname err)) -}
131− putIState i)
375+ where
132−
376+ -- | The type of the udpate function.
133− getBoundImpls (PPi (Imp _ _ _ _) n ty sc) = (n, ty) : getBoundImpls sc
377+ generateTy :: PDecl
134− getBoundImpls _ = []
378+ generateTy = PTy pdoc [] psyn fc [] set_pname $ PPi expl (nsroot pname) pty (PPi expl recName sty (substInput sty))
135−
379+ where substInput = substMatches [(cname, PRef fc (nsroot pname))]
136− getImplB k (PPi (Imp l s _ _) n Placeholder sc)
380+
137− = getImplB k sc
381+ -- | The "_set" name.
138− getImplB k (PPi (Imp l s p fa) n ty sc)
382+ set_pname :: Name
139− = getImplB (\x -> k (PPi (Imp l s p fa) n ty x)) sc
383+ set_pname = set_name pname
140− getImplB k (PPi _ n ty sc)
384+
141− = getImplB k sc
385+ set_name :: Name -> Name
142− getImplB k _ = k
386+ set_name (UN n) = sUN ("set_" ++ str n)
143−
387+ set_name (MN i n) = sMN i ("set_" ++ str n)
144− renameBs (PImp _ _ _ _ _ : ps) (PPi p n ty s)
388+ set_name (NS n s) = NS (set_name n) s
145− = PPi p (mkImp n) ty (renameBs ps (substMatch n (PRef fc (mkImp n)) s))
389+ set_name n = n
146− renameBs (_:ps) (PPi p n ty s) = PPi p n ty (renameBs ps s)
390+
147− renameBs _ t = t
391+ -- | The left-hand side of the update function.
148−
392+ generateLhs :: PTerm
149− getProjs acc (PPi _ n ty s) = getProjs ((n, ty) : acc) s
393+ generateLhs = PApp fc (PRef fc set_pname) [pexp $ PRef fc pname_in, pexp constructorPattern]
150− getProjs acc r = reverse acc
394+ where
151−
395+ constructorPattern :: PTerm
152− getFieldNames (PPi (Exp _ _ _) n _ s) = n : getFieldNames s
396+ constructorPattern = PApp fc (PRef fc cn) args
153− getFieldNames (PPi _ _ _ s) = getFieldNames s
397+
154− getFieldNames _ = []
398+ -- | The "_in" name.
155−
399+ pname_in :: Name
156− getRecTy (PPi _ n ty s) = getRecTy s
400+ pname_in = in_name rootname
157− getRecTy t = t
401+
158−
402+ rootname :: Name
159− -- make sure we pick a consistent name for parameters; any name will do
403+ rootname = nsroot pname
160− -- otherwise
404+
161− getRecNameMap x ppos (PApp fc t args)
405+ -- | The right-hand side of the update function.
162− = mapMaybe toMN (zip [0..] (map getTm args))
406+ generateRhs :: PTerm
407+ generateRhs = PApp fc (PRef fc cn) (newArgs i args)
163 where
408 where
164− toMN (i, PRef fc n)
409+ newArgs :: Int -> [PArg] -> [PArg]
165− | i `elem` ppos = Just (n, PRef fc (mkp n))
410+ newArgs 0 (_ : rest) = (asArg plicity (nsroot cname) (PRef fc pname_in)) : rest
166− | otherwise = Just (n, PRef fc (sMN 0 (show n ++ x)))
411+ newArgs i (x : rest) = x : (newArgs (i-1) rest)
167− toMN _ = Nothing
412+ newArgs _ [] = []
168− getRecNameMap x _ _ = []
413+
169−
414+-- | Post-fixes a name with "_in".
170− rec = sMN 0 "rec"
415+in_name :: Name -> Name
171−
416+in_name (UN n) = sMN 0 (str n ++ "_in")
172− -- only UNs propagate properly as parameters (bit of a hack then...)
173− mkp (UN n) = sUN ("_p_" ++ str n)
174− mkp (MN i n) = sMN i ("p_" ++ str n)
417+in_name (MN i n) = sMN i (str n ++ "_in")
175− mkp (NS n s) = NS (mkp n) s
418+in_name (NS n s) = NS (in_name n) s
176−
419+in_name n = n
177− mkImp (UN n) = sUN ("implicit_" ++ str n)
420+
178− mkImp (MN i n) = sMN i ("implicit_" ++ str n)
421+-- | Creates a PArg with a given plicity, name, and term.
179− mkImp (NS n s) = NS (mkImp n) s
422+asArg :: Plicity -> Name -> PTerm -> PArg
180−
423+asArg (Imp os _ _ _) n t = PImp 0 False os n t
181− mkType (UN n) = sUN ("set_" ++ str n)
424+asArg (Exp os _ _) n t = PExp 0 os n t
182− mkType (MN i n) = sMN i ("set_" ++ str n)
425+asArg (Constraint os _) n t = PConstraint 0 os n t
183− mkType (NS n s) = NS (mkType n) s
426+asArg (TacImp os _ s) n t = PTacImplicit 0 os n s t
184−
427+
185− mkProj recty substs cimp ((pn_in, pty), pos)
428+-- | Machine name "rec".
186− = do let pn = expandNS syn pn_in -- projection name
429+recName :: Name
187− -- use pn_in in the indices, consistently, to avoid clash
430+recName = sMN 0 "rec"
188− let pfnTy = PTy emptyDocstring [] defaultSyntax fc [] pn
431+
189− (PPi expl rec recty
432+recRef = PRef emptyFC recName
190− (substMatches substs pty))
433+
191− let pls = repeat Placeholder
434+projectInType :: [(Name, Name)] -> PTerm -> PTerm
192− let before = pos
435+projectInType xs = mapPT st
193− let after = length substs - (pos + 1)
436+ where
194− let args = take before pls ++ PRef fc (mkp pn_in) : take after pls
437+ st :: PTerm -> PTerm
195− let iargs = map implicitise (zip cimp args)
438+ st (PRef fc n)
196− let lhs = PApp fc (PRef fc pn)
439+ | Just pn <- lookup n xs = PApp fc (PRef fc pn) [pexp recRef]
197− [pexp (PApp fc (PRef fc cn) iargs)]
440+ st t = t
198− let rhs = PRef fc (mkp pn_in)
441+
199− let pclause = PClause fc pn lhs [] rhs []
442+-- | Creates an PArg from a plicity and a name where the term is a PRef.
200− return [pfnTy, PClauses fc [] pn [pclause]]
443+asPRefArg :: Plicity -> Name -> PArg
201−
444+asPRefArg p n = asArg p (nsroot n) $ PRef emptyFC (nsroot n)
202− implicitise (pa, t) = pa { getTm = t }
203−
204− -- If the 'pty' we're updating includes anything in 'substs', we're
205− -- updating the type as well, so use recty', otherwise just use
206− -- recty
207− mkUpdate recty inames extras fnames k num ((pn, pty), pos)
208− = do let setname = expandNS syn $ mkType pn
209− let valname = sMN 0 "updateval"
210− let pn_out = sMN 0 (show pn ++ "_out")
211− let pn_in = sMN 0 (show pn ++ "_in")
212− let recty_in = substMatches [(pn, PRef fc pn_in)] recty
213− let recty_out = substMatches [(pn, PRef fc pn_out)] recty
214− let pt = substMatches inames $
215− k (implBindUp extras inames (PPi expl pn_out pty
216− (PPi expl rec recty_in recty_out)))
217− let pfnTy = PTy emptyDocstring [] defaultSyntax fc [] setname pt
218−-- let pls = map (\x -> PRef fc (sMN x ("field" ++ show x))) [0..num-1]
219− let inames_imp = map (\ (x,_) -> (x, Placeholder)) inames
220− let pls = map (\x -> substMatches inames_imp (PRef fc x)) fnames
221− let lhsArgs = pls
222− let rhsArgs = take pos pls ++ (PRef fc valname) :
223− drop (pos + 1) pls
224− let before = pos
225− let pclause = PClause fc setname (PApp fc (PRef fc setname)
226− [pexp (PRef fc valname),
227− pexp (PApp fc (PRef fc cn)
228− (map pexp lhsArgs))])
229− []
230− (PApp fc (PRef fc cn)
231− (map pexp rhsArgs)) []
232− return (pn, pfnTy, PClauses fc [] setname [pclause])
233−
234− implBindUp [] is t = t
235− implBindUp ((n, ty):ns) is t
236− = let n' = case lookup n is of
237− Just (PRef _ x) -> x
238− _ -> n in
239− if n `elem` allNamesIn t
240− then PPi impl n' ty (implBindUp ns is t)
241− else implBindUp ns is t
242
445
src/Idris/ElabDecls.hs+6−4
@@ -238,14 +238,16 @@ elabDecl' what info (PClass doc s f cs n ps pdocs fds ds)
238 elabClass info (s { syn_params = [] }) doc f cs n ps pdocs fds ds
238 elabClass info (s { syn_params = [] }) doc f cs n ps pdocs fds ds
239elabDecl' what info (PInstance doc argDocs s f cs n ps t expn ds)
239elabDecl' what info (PInstance doc argDocs s f cs n ps t expn ds)
240 = do iLOG $ "Elaborating instance " ++ show n
240 = do iLOG $ "Elaborating instance " ++ show n
241− elabInstance info s doc argDocs what f cs n ps t expn ds
241+ elabInstance info s doc argDocs what f cs n ps t expn ds
242−elabDecl' what info (PRecord doc s f tyn ty opts cdoc cn cty)
242+elabDecl' what info (PRecord doc rsyn fc opts name ps pdocs fs cname cdoc csyn)
243 | what /= ETypes
243 | what /= ETypes
244− = do iLOG $ "Elaborating record " ++ show tyn
244+ = do iLOG $ "Elaborating record " ++ show name
245− elabRecord info s doc f tyn ty opts cdoc cn cty
245+ elabRecord info doc rsyn fc opts name ps pdocs fs cname cdoc csyn
246+{-
246 | otherwise
247 | otherwise
247 = do iLOG $ "Elaborating [type of] " ++ show tyn
248 = do iLOG $ "Elaborating [type of] " ++ show tyn
248 elabData info s doc [] f [] (PLaterdecl tyn ty)
249 elabData info s doc [] f [] (PLaterdecl tyn ty)
250+-}
249elabDecl' _ info (PDSL n dsl)
251elabDecl' _ info (PDSL n dsl)
250 = do i <- getIState
252 = do i <- getIState
251 putIState (i { idris_dsls = addDef n dsl (idris_dsls i) })
253 putIState (i { idris_dsls = addDef n dsl (idris_dsls i) })
src/Idris/IBC.hs+6−2
@@ -1173,7 +1173,7 @@ instance (Binary t) => Binary (PDecl' t) where
1173 PNamespace x1 x2 -> do putWord8 5
1173 PNamespace x1 x2 -> do putWord8 5
1174 put x1
1174 put x1
1175 put x2
1175 put x2
1176− PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 ->
1176+ PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 ->
1177 do putWord8 6
1177 do putWord8 6
1178 put x1
1178 put x1
1179 put x2
1179 put x2
@@ -1184,6 +1184,8 @@ instance (Binary t) => Binary (PDecl' t) where
1184 put x7
1184 put x7
1185 put x8
1185 put x8
1186 put x9
1186 put x9
1187+ put x10
1188+ put x11
1187 PClass x1 x2 x3 x4 x5 x6 x7 x8 x9
1189 PClass x1 x2 x3 x4 x5 x6 x7 x8 x9
1188 -> do putWord8 7
1190 -> do putWord8 7
1189 put x1
1191 put x1
@@ -1285,7 +1287,9 @@ instance (Binary t) => Binary (PDecl' t) where
1285 x7 <- get
1287 x7 <- get
1286 x8 <- get
1288 x8 <- get
1287 x9 <- get
1289 x9 <- get
1290+ x10 <- get
1291+ x11 <- get
1288− return (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9)
1292+ return (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11)
1289 7 -> do x1 <- get
1293 7 -> do x1 <- get
1290 x2 <- get
1294 x2 <- get
1291 x3 <- get
1295 x3 <- get
src/Idris/ParseData.hs+83−16
@@ -42,31 +42,29 @@ Record ::=
42 DocComment Accessibility? 'record' FnName TypeSig 'where' OpenBlock Constructor KeepTerminator CloseBlock;
42 DocComment Accessibility? 'record' FnName TypeSig 'where' OpenBlock Constructor KeepTerminator CloseBlock;
43-}
43-}
44record :: SyntaxInfo -> IdrisParser PDecl
44record :: SyntaxInfo -> IdrisParser PDecl
45−record syn = do (doc, argDocs, acc, opts) <- try (do
45+record syn = do (doc, paramDocs, acc, opts) <- try (do
46− (doc, argDocs) <- option noDocs docComment
46+ (doc, paramDocs) <- option noDocs docComment
47 ist <- get
47 ist <- get
48 let doc' = annotCode (tryFullExpr syn ist) doc
48 let doc' = annotCode (tryFullExpr syn ist) doc
49− argDocs' = [ (n, annotCode (tryFullExpr syn ist) d)
49+ paramDocs' = [ (n, annotCode (tryFullExpr syn ist) d)
50− | (n, d) <- argDocs ]
50+ | (n, d) <- paramDocs ]
51 acc <- optional accessibility
51 acc <- optional accessibility
52 opts <- dataOpts []
52 opts <- dataOpts []
53− reserved "record"
53+ co <- recordI
54− return (doc', argDocs', acc, opts))
54+ return (doc', paramDocs', acc, opts ++ co))
55 fc <- getFC
55 fc <- getFC
56 tyn_in <- fnName
56 tyn_in <- fnName
57− lchar ':'
58− ty <- typeExpr (allowImp syn)
59 let tyn = expandNS syn tyn_in
57 let tyn = expandNS syn tyn_in
60− reserved "where"
61− (cdoc, cargDocs, cn, cty, _, _) <- indentedBlockS (constructor syn)
62− accData acc tyn [cn]
63 let rsyn = syn { syn_namespace = show (nsroot tyn) :
58 let rsyn = syn { syn_namespace = show (nsroot tyn) :
64− syn_namespace syn }
59+ syn_namespace syn }
65− let fns = getRecNames rsyn cty
60+ params <- manyTill (recordParameter rsyn) (reserved "where")
66− mapM_ (\n -> addAcc n acc) fns
61+ (fields, cname, cdoc) <- indentedBlockS $ agdaStyleBody rsyn tyn
62+ case cname of
63+ Just cn' -> accData acc tyn [cn']
64+ Nothing -> return ()
67− return $ PRecord doc rsyn fc tyn ty opts cdoc cn cty
65+ return $ PRecord doc rsyn fc opts tyn params paramDocs fields cname cdoc syn
68 <?> "record type declaration"
66 <?> "record type declaration"
69− where
67+ where
70 getRecNames :: SyntaxInfo -> PTerm -> [Name]
68 getRecNames :: SyntaxInfo -> PTerm -> [Name]
71 getRecNames syn (PPi _ n _ sc) = [expandNS syn n, expandNS syn (mkType n)]
69 getRecNames syn (PPi _ n _ sc) = [expandNS syn n, expandNS syn (mkType n)]
72 ++ getRecNames syn sc
70 ++ getRecNames syn sc
@@ -76,6 +74,71 @@ record syn = do (doc, argDocs, acc, opts) <- try (do
76 toFreeze (Just Frozen) = Just Hidden
74 toFreeze (Just Frozen) = Just Hidden
77 toFreeze x = x
75 toFreeze x = x
78
76
77+ agdaStyleBody :: SyntaxInfo -> Name -> IdrisParser ([((Maybe Name), Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))], Maybe Name, Docstring (Either Err PTerm))
78+ agdaStyleBody syn tyn = do
79+ ist <- get
80+ fc <- getFC
81+
82+ (constructorName, constructorDoc) <- option (Nothing, emptyDocstring)
83+ (do (doc, _) <- option noDocs docComment
84+ n <- constructor
85+ return (Just n, doc))
86+
87+ let constructorDoc' = annotate syn ist constructorDoc
88+
89+ fields <- many . indented $ field syn
90+
91+ return (fields, constructorName, constructorDoc')
92+ where
93+ field :: SyntaxInfo -> IdrisParser ((Maybe Name), Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))
94+ field syn = do doc <- optional docComment
95+ c <- optional $ lchar '{'
96+ n <- (do n <- fnName
97+ return $ Just (expandNS syn n))
98+ <|> (do symbol "_"
99+ return Nothing)
100+ lchar ':'
101+ t <- typeExpr (allowImp syn)
102+ p <- endPlicity c
103+ ist <- get
104+ let doc' = case doc of -- Temp: Throws away any possible arg docs
105+ Just (d,_) -> Just $ annotate syn ist d
106+ Nothing -> Nothing
107+ return (n, p, t, doc')
108+
109+ constructor :: IdrisParser Name
110+ constructor = (reserved "constructor") *> fnName
111+
112+ endPlicity :: Maybe Char -> IdrisParser Plicity
113+ endPlicity (Just _) = do lchar '}'
114+ return impl
115+ endPlicity Nothing = return expl
116+
117+ annotate :: SyntaxInfo -> IState -> Docstring () -> Docstring (Either Err PTerm)
118+ annotate syn ist = annotCode $ tryFullExpr syn ist
119+
120+recordParameter :: SyntaxInfo -> IdrisParser (Name, Plicity, PTerm)
121+recordParameter syn =
122+ (do lchar '('
123+ (n, pt) <- (namedTy syn <|> onlyName syn)
124+ lchar ')'
125+ return (n, expl, pt))
126+ <|>
127+ (do (n, pt) <- onlyName syn
128+ return (n, expl, pt))
129+
130+ where
131+ namedTy :: SyntaxInfo -> IdrisParser (Name, PTerm)
132+ namedTy syn =
133+ do n <- fnName
134+ lchar ':'
135+ ty <- typeExpr (allowImp syn)
136+ return (expandNS syn n, ty)
137+ onlyName :: SyntaxInfo -> IdrisParser (Name, PTerm)
138+ onlyName syn =
139+ do n <- fnName
140+ return (expandNS syn n, PType)
141+
79{- | Parses data declaration type (normal or codata)
142{- | Parses data declaration type (normal or codata)
80DataI ::= 'data' | 'codata';
143DataI ::= 'data' | 'codata';
81-}
144-}
@@ -83,6 +146,10 @@ dataI :: IdrisParser DataOpts
83dataI = do reserved "data"; return []
146dataI = do reserved "data"; return []
84 <|> do reserved "codata"; return [Codata]
147 <|> do reserved "codata"; return [Codata]
85
148
149+recordI :: IdrisParser DataOpts
150+recordI = do reserved "record"; return []
151+ <|> do reserved "corecord"; return [Codata]
152+
86{- | Parses if a data should not have a default eliminator
153{- | Parses if a data should not have a default eliminator
87DefaultEliminator ::= 'noelim'?
154DefaultEliminator ::= 'noelim'?
88 -}
155 -}
src/Idris/ParseHelpers.hs+3−4
@@ -189,8 +189,6 @@ docComment = do dc <- pushIndent *> docCommentLine
189 eol ; someSpace
189 eol ; someSpace
190 return (n, docs)
190 return (n, docs)
191
191
192−
193−
194-- | Parses some white space
192-- | Parses some white space
195whiteSpace :: MonadicParsing m => m ()
193whiteSpace :: MonadicParsing m => m ()
196whiteSpace = Tok.whiteSpace
194whiteSpace = Tok.whiteSpace
@@ -224,14 +222,15 @@ idrisStyle = IdentifierStyle _styleName _styleStart _styleLetter _styleReserved
224 where _styleName = "Idris"
222 where _styleName = "Idris"
225 _styleStart = satisfy isAlpha <|> oneOf "_"
223 _styleStart = satisfy isAlpha <|> oneOf "_"
226 _styleLetter = satisfy isAlphaNum <|> oneOf "_'."
224 _styleLetter = satisfy isAlphaNum <|> oneOf "_'."
227− _styleReserved = HS.fromList ["let", "in", "data", "codata", "record", "Type",
225+ _styleReserved = HS.fromList ["let", "in", "data", "codata", "record", "corecord", "Type",
228 "do", "dsl", "import", "impossible",
226 "do", "dsl", "import", "impossible",
229 "case", "of", "total", "partial", "mutual",
227 "case", "of", "total", "partial", "mutual",
230 "infix", "infixl", "infixr", "rewrite",
228 "infix", "infixl", "infixr", "rewrite",
231 "where", "with", "syntax", "proof", "postulate",
229 "where", "with", "syntax", "proof", "postulate",
232 "using", "namespace", "class", "instance", "parameters",
230 "using", "namespace", "class", "instance", "parameters",
233 "public", "private", "abstract", "implicit",
231 "public", "private", "abstract", "implicit",
232+ "quoteGoal", "constructor",
234− "quoteGoal", "if", "then", "else"]
233+ "if", "then", "else"]
235
234
236char :: MonadicParsing m => Char -> m Char
235char :: MonadicParsing m => Char -> m Char
237char = Chr.char
236char = Chr.char
test/basic001/reg005.dSYM/Contents/Info.plistnew file+20
@@ -0,0 +1,20 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+<plist version="1.0">
4+ <dict>
5+ <key>CFBundleDevelopmentRegion</key>
6+ <string>English</string>
7+ <key>CFBundleIdentifier</key>
8+ <string>com.apple.xcode.dsym.reg005</string>
9+ <key>CFBundleInfoDictionaryVersion</key>
10+ <string>6.0</string>
11+ <key>CFBundlePackageType</key>
12+ <string>dSYM</string>
13+ <key>CFBundleSignature</key>
14+ <string>????</string>
15+ <key>CFBundleShortVersionString</key>
16+ <string>1.0</string>
17+ <key>CFBundleVersion</key>
18+ <string>1</string>
19+ </dict>
20+</plist>
test/basic001/reg005.dSYM/Contents/Resources/DWARF/reg005new file

Binary file not shown.

test/corecords001/corecords001.idrnew file+24
@@ -0,0 +1,24 @@
1+module Main
2+
3+corecord Str a where -- Current stream is codata, not a corecord
4+ constructor (::)
5+ head : a
6+ tail : Str a
7+
8+instance Functor Str where
9+ map f (x :: xs) = (f x) :: (map f xs)
10+
11+total -- marked total to check that corecords are indeed treated as coinductive types
12+zeros : Str Int
13+zeros = 0 :: zeros
14+
15+ones : Str Int
16+ones = map (1+) zeros
17+
18+main : IO ()
19+main = do let x = record { head = 1 } zeros
20+ printLn $ head zeros
21+ printLn $ head x
22+ printLn $ head (record { head = 3 } x)
23+ printLn $ head (tail ones)
24+ printLn $ head (tail (record { tail = zeros } ones))
test/corecords001/expectednew file+5
@@ -0,0 +1,5 @@
1+0
2+1
3+3
4+1
5+0
test/corecords001/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+idris $@ corecords001.idr -o corecords001
3+./corecords001
4+rm -f corecords001 corecords001.ibc
test/corecords002/corecords002.idrnew file+24
@@ -0,0 +1,24 @@
1+module Main
2+
3+corecord Foo (n : Nat) where
4+ constructor MkFoo
5+ bar : String
6+ baz : Foo n
7+
8+corecord Blargh where
9+ constructor MkBlargh
10+ num : Nat
11+ argh : Foo num
12+
13+total
14+foo : Foo 7
15+foo = MkFoo "Foo" foo
16+
17+total
18+blargh : Blargh
19+blargh = MkBlargh 7 foo
20+
21+main : IO ()
22+main = do printLn (record { argh->bar } blargh)
23+ printLn (record { argh->baz->bar } blargh)
24+ printLn (record { argh->baz->baz->bar } blargh)
test/corecords002/expectednew file+3
@@ -0,0 +1,3 @@
1+"Foo"
2+"Foo"
3+"Foo"
test/corecords002/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+idris $@ corecords002.idr -o corecords002
3+./corecords002
4+rm -f corecords002 corecords002.ibc
test/docs004/docs004.idrnew file+11
@@ -0,0 +1,11 @@
1+module Main
2+
3+||| Some record Foo
4+||| @a a type
5+record Foo a where
6+ ||| Constructor for Foo
7+ constructor MkFoo
8+ ||| A field bar
9+ bar : Nat
10+ ||| A field baz
11+ baz : Bool
test/docs004/expectednew file+15
@@ -0,0 +1,15 @@
1+MkFoo : (bar : Nat) -> (baz : Bool) -> Foo a
2+ Constructor for Foo
3+ Arguments:
4+ (implicit) a : Type -- a type
5+
6+ bar : Nat -- A field bar
7+
8+ baz : Bool -- A field baz
9+
10+bar : (rec : Foo a) -> Nat
11+ A field bar
12+
13+baz : (rec : Foo a) -> Bool
14+ A field baz
15+
test/docs004/inputnew file+3
@@ -0,0 +1,3 @@
1+:doc MkFoo
2+:doc bar
3+:doc baz
test/docs004/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris --quiet --nocolor --consolewidth 80 docs004.idr < input
3+rm *.ibc
test/records001/test011.idr+10−8
@@ -2,14 +2,16 @@ module Main
2
2
3import Data.Vect
3import Data.Vect
4
4
5−record Foo : Nat -> Type where
5+record Foo (n : Nat) where
6+ constructor MkFoo
6− MkFoo : (name : String) ->
7+ name : String
7− (things : Vect n a) ->
8+ things : Vect n a
8− (more_things : Vect m b) ->
9+ more_things : Vect m b
9− Foo n
10+
10−
11−record Person : Type where
11+record Person where
12+ constructor MkPerson
12− MkPerson : (name : String) -> (age : Int) -> Person
13+ name : String
14+ age : Int
13
15
14testFoo : Foo 3
16testFoo : Foo 3
15testFoo = MkFoo "name" [1,2,3] [4,5,6,7]
17testFoo = MkFoo "name" [1,2,3] [4,5,6,7]
test/records002/record002.idr+7−6
@@ -1,11 +1,12 @@
1−
2−record Foo : Nat -> Type where
1+record Foo (param : Nat) where
3− MkFoo : (param : Nat) -> (num : Int) -> Foo param
2+ constructor MkFoo
3+ num : Int
4
4
5instance Show (Foo n) where
5instance Show (Foo n) where
6− show f = show (param f) ++ ", " ++ show (num f)
6+ show f = show (param_param f) ++ ", " ++ show (num f)
7
7
8main : IO ()
8main : IO ()
9−main = do let x = MkFoo 10 20
9+main = do let x = MkFoo {param=10} 20
10− putStrLn (show (record { param = 42 } x))
10+ putStrLn (show (record { param_param = 42 } x))
11 putStrLn (show (record { num = 42 } x))
11 putStrLn (show (record { num = 42 } x))
12+
test/records003/records003.idr+24−25
@@ -1,47 +1,46 @@
1−record Person : Nat -> Type where
1+record Person (age : Nat) where
2+ constructor MkPerson
2− MkPerson : (name : String) ->
3+ name : String
3− (age : Nat) ->
4− Person age
5
4
6−record Event : Type where
5+record Event where
6+ constructor MkEvent
7+ name : String
7− MkEvent : (name : String) -> (organiser : Person a) -> Event
8+ organiser : Person a
8
9
9−record Meeting : Int -> Type where
10+record Meeting (year : Int) where
11+ constructor MkMeeting
10− MkMeeting : (event : Event) ->
12+ event : Event
11− (organiser : Person a) ->
13+ organiser : Person a
12− (year : Int) ->
13− Meeting year
14
14
15new_organiser : String -> List (Meeting x) -> List (Meeting x)
15new_organiser : String -> List (Meeting x) -> List (Meeting x)
16new_organiser n = map (record { event->organiser->name = n })
16new_organiser n = map (record { event->organiser->name = n })
17
17
18next_year : Meeting x -> Meeting (x+1)
18next_year : Meeting x -> Meeting (x+1)
19−next_year m = record { organiser->age
19+next_year m = record { organiser->param_age
20− = record { organiser->age } m + 1,
20+ = record { organiser->param_age } m + 1,
21− event->organiser->age
21+ event->organiser->param_age
22− = record { event->organiser->age } m + 1,
22+ = record { event->organiser->param_age } m + 1,
23− year = _ } m
23+ param_year = _ } m
24
24
25fred : Person 20
25fred : Person 20
26−fred = MkPerson "Fred" _
26+fred = MkPerson "Fred"
27
27
28jim : Person 29
28jim : Person 29
29−jim = MkPerson "Jim" 29
29+jim = MkPerson {age=29} "Jim"
30
30
31idm : Event
31idm : Event
32idm = MkEvent "Idris Developers Meeting" fred
32idm = MkEvent "Idris Developers Meeting" fred
33
33
34idm_gbg : Meeting 2014
34idm_gbg : Meeting 2014
35−idm_gbg = MkMeeting idm jim _
35+idm_gbg = MkMeeting idm jim
36
36
37test : Meeting 2015
37test : Meeting 2015
38test = next_year idm_gbg
38test = next_year idm_gbg
39
39
40main : IO ()
40main : IO ()
41main = do printLn (record { event->organiser->name } test)
41main = do printLn (record { event->organiser->name } test)
42− printLn (record { event->organiser->age } test)
42+ printLn (record { event->organiser->param_age } test)
43− printLn (record { event->organiser->age } idm_gbg)
43+ printLn (record { event->organiser->param_age } idm_gbg)
44− printLn (record { organiser->age } test)
44+ printLn (record { organiser->param_age } test)
45− printLn (record { organiser->age } idm_gbg)
45+ printLn (record { organiser->param_age } idm_gbg)
46− printLn (record { year } idm_gbg)
46+ printLn (record { param_year } idm_gbg)
47−