Skip to content

Commit a379dea

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

File tree

3 files changed

+200
-1
lines changed

3 files changed

+200
-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: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
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+
82+
export
83+
encode : {0 A : Type} -> (f : FormatOf A) -> Encode A (ByteStream)
84+
encode End () = Just []
85+
encode (Pure x) _ = Just []
86+
encode (Skip f def) () = encode f def
87+
encode (Repeat Z f) [] = Just []
88+
encode (Repeat (S len) f) (x :: xs) =
89+
[| encode f x <+> encode (Repeat len f) xs |]
90+
encode (Bind f1 f2) (x ** y) =
91+
[| encode f1 x <+> encode (f2 x) y |]
92+
encode (Custom f) x = f.encode x
93+
94+
95+
--------------------
96+
-- CUSTOM FORMATS --
97+
--------------------
98+
99+
100+
public export
101+
u8 : FormatOf Nat
102+
u8 = Custom (MkCustomFormat
103+
{ Rep = Nat
104+
, decode = map cast decodeU8
105+
, encode = encodeU8 . cast {to = Bits8}
106+
})
107+
108+
109+
public export
110+
u16Le : FormatOf Nat
111+
u16Le = Custom (MkCustomFormat
112+
{ Rep = Nat
113+
, decode = map cast (decodeU16 LE)
114+
, encode = encodeU16 LE . cast {to = Bits16}
115+
})
116+
117+
118+
public export
119+
u16Be : FormatOf Nat
120+
u16Be = Custom (MkCustomFormat
121+
{ Rep = Nat
122+
, decode = map cast (decodeU16 BE)
123+
, encode = encodeU16 BE . cast {to = Bits16}
124+
})
125+
126+
127+
-----------------
128+
-- EXPERIMENTS --
129+
-----------------
130+
131+
132+
public export
133+
record Format where
134+
constructor MkFormat
135+
0 Repr : Type
136+
Format : FormatOf Repr
137+
138+
139+
either : (cond : Bool) -> FormatOf a -> FormatOf b -> FormatOf (if cond then a else b)
140+
either True f1 _ = f1
141+
either False _ f2 = f2
142+
143+
orPure : (cond : Bool) -> FormatOf a -> (def : a) -> FormatOf a
144+
orPure True f _ = f
145+
orPure False _ def = Pure def
146+
147+
148+
-- Reproduction of difficulties in OpenType format
149+
150+
151+
Flag : Type
152+
Flag = (flag : Nat ** repeat : Nat ** ())
153+
154+
(.repeat) : Flag -> Nat
155+
(.repeat) (_ ** repeat ** _) = repeat
156+
157+
158+
-- def flag = {
159+
-- flag <- u8,
160+
-- repeat <- match ((u8_and flag 8) != (0 : U8)) {
161+
-- true => u8,
162+
-- false => succeed U8 0,
163+
-- },
164+
-- };
165+
flag : FormatOf Flag
166+
flag = do
167+
flag <- u8
168+
repeat <- case flag of
169+
0 => u8
170+
_ => Pure {A = Nat} 0
171+
Pure ()
172+
173+
174+
SimpleGlyph : Type
175+
SimpleGlyph = (flag : Flag ** Nat)
176+
177+
178+
-- def simple_glyph = fun (number_of_contours : U16) => {
179+
-- ...
180+
-- let flag_repeat = fun (f : Repr flag) => f.repeat + (1 : U8),
181+
-- ...
182+
-- };
183+
simple_glyph : FormatOf SimpleGlyph
184+
simple_glyph = do
185+
flag <- flag
186+
Pure (flag.repeat + 1)

0 commit comments

Comments
 (0)