Skip to content

Commit a7c7bb6

Browse files
committed
Try out the opentype issue with indexed types
1 parent 41832aa commit a7c7bb6

File tree

3 files changed

+223
-1
lines changed

3 files changed

+223
-1
lines changed

experiments/idris/fathom.ipkg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ modules = Fathom
2020
, Fathom.Data.Refine
2121
, Fathom.Data.Word
2222
, Fathom.Closed.IndexedInductive
23+
, Fathom.Closed.IndexedInductiveCustom
2324
, Fathom.Closed.InductiveRecursive
2425
, Fathom.Closed.InductiveRecursiveCustom
2526
, Fathom.Open.Record

experiments/idris/src/Fathom/Base.idr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ parameters (Source, Target : Type)
6767
EncodePart = Encode (Source, Target) Target
6868

6969

70+
namespace DecodePart
71+
72+
public export
73+
pure : {0 S, T : Type} -> S -> DecodePart S T
74+
pure source target = Just (source, target)
75+
76+
public export
77+
map : {0 S1, S2, T : Type} -> (S1 -> S2) -> DecodePart S1 T -> DecodePart S2 T
78+
map f decode target =
79+
Prelude.map (\(source, target') => (f source, target)) (decode target)
80+
81+
7082
parameters {0 Source, Target : Type}
7183

7284
public export
@@ -151,7 +163,7 @@ namespace ByteStream
151163
splitLen : (n : Nat) -> Colist a -> Maybe (Vect n a, Colist a)
152164
splitLen 0 _ = Nothing
153165
splitLen (S k) [] = Nothing
154-
splitLen (S k) (x :: rest) = map (\(xs, rest') => (x :: xs, rest')) (splitLen k rest)
166+
splitLen (S k) (x :: rest) = Prelude.map (\(xs, rest') => (x :: xs, rest')) (splitLen k rest)
155167

156168

157169
export
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
||| A closed universe of format descriptions as an inductive type, where the
2+
||| in-memory representation is tracked as an index on the type.
3+
4+
module Fathom.Closed.IndexedInductiveCustom
5+
6+
7+
import Data.Colist
8+
import Data.Vect
9+
10+
import Fathom.Base
11+
12+
13+
-------------------------
14+
-- FORMAT DESCRIPTIONS --
15+
-------------------------
16+
17+
18+
||| A custom format description.
19+
|||
20+
||| We’d prefer to just import `Fathom.Open.Record`, but Idris’ imports are a
21+
||| bit temperamental and result in ambiguities when importing modules that
22+
||| contain types of the same name as those defined in the current module.
23+
public export
24+
record CustomFormat where
25+
constructor MkCustomFormat
26+
Rep : Type
27+
decode : Decode (Rep, ByteStream) ByteStream
28+
encode : Encode Rep ByteStream
29+
30+
31+
||| Universe of format descriptions indexed by their machine representations
32+
public export
33+
data FormatOf : (0 A : Type) -> Type where
34+
End : FormatOf Unit
35+
Fail : FormatOf Void
36+
Pure : {0 A : Type} -> (x : A) -> FormatOf A
37+
Skip : {0 A : Type} -> (f : FormatOf A) -> (def : A) -> FormatOf Unit
38+
Repeat : {0 A : Type} -> (len : Nat) -> FormatOf A -> FormatOf (Vect len A)
39+
Bind : {0 A : Type} -> {0 B : A -> Type} -> (f : FormatOf A) -> ((x : A) -> FormatOf (B x)) -> FormatOf (x : A ** B x)
40+
Custom : (f : CustomFormat) -> FormatOf f.Rep
41+
42+
43+
-- Support for do notation
44+
45+
public export
46+
pure : {0 A : Type} -> (x : A) -> FormatOf A
47+
pure = Pure
48+
49+
public export
50+
(>>=) : {0 A : Type} -> {0 B : A -> Type} -> (f : FormatOf A) -> ((x : A) -> FormatOf (B x)) -> FormatOf (x : A ** B x)
51+
(>>=) = Bind
52+
53+
54+
---------------------------
55+
-- ENCODER/DECODER PAIRS --
56+
---------------------------
57+
58+
59+
export
60+
decode : {0 A : Type} -> (f : FormatOf A) -> Decode (A, ByteStream) (ByteStream)
61+
decode End [] = Just ((), [])
62+
decode End (_::_) = Nothing
63+
decode Fail _ = Nothing
64+
decode (Pure x) buffer =
65+
Just (x, buffer)
66+
decode (Skip f _) buffer = do
67+
(x, buffer') <- decode f buffer
68+
Just ((), buffer')
69+
decode (Repeat 0 f) buffer =
70+
Just ([], buffer)
71+
decode (Repeat (S len) f) buffer = do
72+
(x, buffer') <- decode f buffer
73+
(xs, buffer'') <- decode (Repeat len f) buffer'
74+
Just (x :: xs, buffer'')
75+
decode (Bind f1 f2) buffer = do
76+
(x, buffer') <- decode f1 buffer
77+
(y, buffer'') <- decode (f2 x) buffer'
78+
Just ((x ** y), buffer'')
79+
decode (Custom f) buffer = f.decode buffer
80+
81+
-- export
82+
-- decode : {0 A : Type} -> (f : FormatOf A) -> Decode (A, ByteStream) (ByteStream)
83+
-- decode End
84+
-- = \buffer => case buffer of
85+
-- [] => Just ((), [])
86+
-- _::_ => Nothing
87+
-- decode Fail
88+
-- = const Nothing
89+
-- decode (Pure x)
90+
-- = pure (MkSing x)
91+
-- decode (Skip f _)
92+
-- = do _ <- decode f
93+
-- pure ()
94+
-- decode (Repeat 0 f) = pure []
95+
-- decode (Repeat (S len) f)
96+
-- = do x <- decode f
97+
-- xs <- decode (Repeat len f)
98+
-- pure (x :: xs)
99+
-- decode (Bind f1 f2)
100+
-- = do x <- decode f1
101+
-- y <- decode (f2 x)
102+
-- pure (x ** y)
103+
104+
105+
export
106+
encode : {0 A : Type} -> (f : FormatOf A) -> Encode A (ByteStream)
107+
encode End () = Just []
108+
encode (Pure x) _ = Just []
109+
encode (Skip f def) () = encode f def
110+
encode (Repeat Z f) [] = Just []
111+
encode (Repeat (S len) f) (x :: xs) =
112+
[| encode f x <+> encode (Repeat len f) xs |]
113+
encode (Bind f1 f2) (x ** y) =
114+
[| encode f1 x <+> encode (f2 x) y |]
115+
encode (Custom f) x = f.encode x
116+
117+
118+
--------------------
119+
-- CUSTOM FORMATS --
120+
--------------------
121+
122+
123+
public export
124+
u8 : FormatOf Nat
125+
u8 = Custom (MkCustomFormat
126+
{ Rep = Nat
127+
, decode = map cast decodeU8
128+
, encode = encodeU8 . cast {to = Bits8}
129+
})
130+
131+
132+
public export
133+
u16Le : FormatOf Nat
134+
u16Le = Custom (MkCustomFormat
135+
{ Rep = Nat
136+
, decode = map cast (decodeU16 LE)
137+
, encode = encodeU16 LE . cast {to = Bits16}
138+
})
139+
140+
141+
public export
142+
u16Be : FormatOf Nat
143+
u16Be = Custom (MkCustomFormat
144+
{ Rep = Nat
145+
, decode = map cast (decodeU16 BE)
146+
, encode = encodeU16 BE . cast {to = Bits16}
147+
})
148+
149+
150+
-----------------
151+
-- EXPERIMENTS --
152+
-----------------
153+
154+
155+
public export
156+
record Format where
157+
constructor MkFormat
158+
0 Repr : Type
159+
Format : FormatOf Repr
160+
161+
162+
either : (cond : Bool) -> FormatOf a -> FormatOf b -> FormatOf (if cond then a else b)
163+
either True f1 _ = f1
164+
either False _ f2 = f2
165+
166+
orPure : (cond : Bool) -> FormatOf a -> (def : a) -> FormatOf a
167+
orPure True f _ = f
168+
orPure False _ def = Pure def
169+
170+
171+
-- Reproduction of difficulties in OpenType format
172+
173+
174+
Flag : Type
175+
Flag = (flag : Nat ** repeat : Nat ** ())
176+
177+
(.repeat) : Flag -> Nat
178+
(.repeat) (_ ** repeat ** _) = repeat
179+
180+
181+
-- def flag = {
182+
-- flag <- u8,
183+
-- repeat <- match ((u8_and flag 8) != (0 : U8)) {
184+
-- true => u8,
185+
-- false => succeed U8 0,
186+
-- },
187+
-- };
188+
flag : FormatOf Flag
189+
flag = do
190+
flag <- u8
191+
repeat <- case flag of
192+
0 => u8
193+
_ => Pure {A = Nat} 0
194+
Pure ()
195+
196+
197+
SimpleGlyph : Type
198+
SimpleGlyph = (flag : Flag ** Nat)
199+
200+
201+
-- def simple_glyph = fun (number_of_contours : U16) => {
202+
-- ...
203+
-- let flag_repeat = fun (f : Repr flag) => f.repeat + (1 : U8),
204+
-- ...
205+
-- };
206+
simple_glyph : FormatOf SimpleGlyph
207+
simple_glyph = do
208+
flag <- flag
209+
Pure (flag.repeat + 1)

0 commit comments

Comments
 (0)