A SAFE and idiomatic (no corner cutting or strange stuff
under the hood)
implementation of an immutable array
in Haskell aiming for an idiomatic low
memory footprint
by storing chunks
of 256
elements in a fixed vector
(data VF256 a = VF … , i00 :: a, … , iFF :: a }
) by sharing a single
constructor. A side-effect of this approach, is that we achieve O(log₂₅₆ n)
asymptotic time complexity for most operations.
Futhermore, in order to avoid the usage of the following pattern data Present a
= Yes a | No
for when an element is present as it will add a constructor
(overhead) for each element. This is achieved with the usage of ⊥
(bottom
)
combined with Haskells lazy
nature as well as a bitmap
, where each of the
256
elements presence are stored as a single bit
.
Remark: Please see the References
below for Simon Marlows answer
at Stack Overflow
with regard of memory footprint of Haskell data types
.
Basics
Step-by-step insert example with an Array Log₈ with height equal to 0
We have an empty array A of size 64:
□□□□□□□□
▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭
> Remark: ▭ denotes ⊥ (bottom).
The array A is updated with a value of type α on index A₃₁, where index < 64:
□□□▣□□□□
▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭■ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭
The array A is updated with a value of type α on index A₂₉, where index < 64:
□□□▣□□□□
▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭■▭■ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭
The array A is updated with a value of type α on index A₆₃, where index < 64:
□□□▣□□□▣
▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭■▭■ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭▭ ▭▭▭▭▭▭▭■
Step-by-step insert example with an Array Log₄ with height greater than 0
We want to insert a value of type α into index A₃₃ in an Array Log₄ of size 64
□□□□
□□□□ □□□□ □□□□ □□□□
▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭
> Remark: ▭ denotes ⊥ (bottom).
a) Update top bitmap index (node):
33 .>. 4 = 2
2 .&. (4-1) = 2
□□▣□
□□□□ □□□□ □□□□ □□□□
▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭
b) Update next bitmap index (node):
33 .>. 2 = 8
8 .&. (4-1) = 0
□□▣□
□□□□ □□□□ ▣□□□ □□□□
▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭
c) Insert value (leaf):
33 .>. 0 = 33
33 .&. (4-1) = 1
□□▣□
□□□□ □□□□ ▣□□□ □□□□
▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭■▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭ ▭▭▭▭
Code Snippet
src/Data/Array/Log256.hs
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
--------------------------------------------------------------------------------
--
-- Data.Array.Log256, (c) 2020 SPISE MISU ApS
--
--------------------------------------------------------------------------------
{-# LANGUAGE Safe #-}
--------------------------------------------------------------------------------
module Data.Array.Log256
( AL256
--
, height
, length
--
, create
, update
, exists
, lookup
, remove
--
, pprint
, tuples
, tolist
--
, amount
, sparse
, defrag
, sliver
, expand
, reduce
)
where
--------------------------------------------------------------------------------
import Prelude hiding
( length
, lookup
)
import Data.Bits
( Bits
, shiftL
, shiftR
, (.&.)
)
import Data.List
( dropWhile
, foldl'
, takeWhile
)
import Data.Ratio
( Rational
, (%)
)
import Data.Word
( Word8
)
import Data.Vector.Fixed256
( VF256
)
import qualified Data.Vector.Fixed256 as VF
--------------------------------------------------------------------------------
data AL256 a
= A !Integer !(Tree a)
data Tree a
= L !(VF256 a)
| N !(VF256 (Tree a))
instance Show a => Show (AL256 a) where
show (A _ t) = show t
instance Show a => Show (Tree a) where
show = show . helper []
--------------------------------------------------------------------------------
instance Foldable Tree where
foldMap f (L vfa) = foldMap f vfa
foldMap f (N vft) = foldMap (foldMap f) vft
instance Foldable AL256 where
foldMap f (A _ t) = foldMap f t
instance Functor Tree where
fmap f (L vfa) = L $ fmap f vfa
fmap f (N vft) = N $ fmap (fmap f) vft
instance Functor AL256 where
fmap f (A l t) = A l $ fmap f t
--------------------------------------------------------------------------------
length
:: AL256 a
-> Integer
height
:: AL256 a
-> Integer
{-# INLINE length #-}
{-# INLINE height #-}
length (A l _) =
l
height (A l _) =
log256 $ l - 1
--------------------------------------------------------------------------------
create
:: Integer
-> AL256 a
update
:: Integer
-> a
-> AL256 a
-> AL256 a
exists
:: Integer
-> AL256 a
-> Bool
lookup
:: Integer
-> AL256 a
-> a
remove
:: Integer
-> AL256 a
-> AL256 a
{-# INLINE create #-}
{-# INLINE update #-}
{-# INLINE exists #-}
{-# INLINE lookup #-}
{-# INLINE remove #-}
{-| Length must be greater than 0. Devs responsability to call inside bounds
-}
create l
| l > aux = A l $ N VF.create
| otherwise = assert (l > 0) msg A l $ L VF.create
where
aux = logmod + 1
msg = "The length of an array must be greater than 0"
{-| Length can be read in O(1). Devs responsability to call inside bounds
-}
update i a (A l t) =
assert (i < l) msg
A l $ aux (loglvl l) t
where
aux _ (L fv) =
L $ k `seq` VF.update k a fv
where
k = i2wrd8 i .&. logmod
aux j (N fv) =
N $ v `seq` VF.update k v fv
where
k = i2wrd8 $ i .>. j .&. logmod
n = j - lograt
c =
if VF.exists k fv
then VF.lookup k fv
else branch n
v = aux n c
msg =
"Index " ++ show i ++ " is out of bounds (length " ++ show l ++ ")"
{-| Length can be read in O(1). Devs responsability to call inside bounds
-}
exists i (A l t) =
assert (i < l) msg
aux (loglvl l) t
where
aux _ (L fv) =
VF.exists k fv
where
k = i2wrd8 i .&. logmod
aux j (N fv) =
e && b
where
k = i2wrd8 $ i .>. j .&. logmod
e = VF.exists k fv
n = j - lograt
b = aux n $ VF.lookup k fv
msg =
"Index " ++ show i ++ " is out of bounds (length " ++ show l ++ ")"
{-| * Length can be read in O(1). Devs responsability to call inside bounds
* Existence can be checked in O(log₂₅₆ n). Devs responsability to check
-}
lookup i al@(A l t) =
assert (i < l) msg0
assert (exists i al) msg1
aux (loglvl l) t
where
aux _ (L fv) =
VF.lookup k fv
where
k = i2wrd8 $ i .&. logmod
aux j (N fv) =
aux n c
where
k = i2wrd8 $ i .>. j .&. logmod
n = j - lograt
c = VF.lookup k fv
msg0 =
"Index " ++ show i ++ " is out of bounds (length " ++ show l ++ ")"
msg1 =
"Index " ++ show i ++ " doesn't contain any element"
{-| * Length can be read in O(1). Devs responsability to call inside bounds
* Existence can be checked in O(log₂₅₆ n). Devs responsability to check
-}
remove i al@(A l t) =
assert (i < l) msg0
assert (exists i al) msg1
A l $ aux (loglvl l) t
where
aux _ (L fv) =
L r
where
k = i2wrd8 $ i .&. logmod
r = VF.remove k fv
aux j (N fv) =
N a
where
k = i2wrd8 $ i .>. j .&. logmod
n = j - lograt
c = VF.lookup k fv
b = aux n c
a =
if vacant b
then VF.remove k fv
else VF.update k b fv
msg0 =
"Index " ++ show i ++ " is out of bounds (length " ++ show l ++ ")"
msg1 =
"Index " ++ show i ++ " doesn't contain any element"
--------------------------------------------------------------------------------
pprint
:: AL256 a
-> String
tuples
:: AL256 a
-> [(Integer, a)]
tolist
:: AL256 a
-> [a]
{-# INLINE pprint #-}
{-# INLINE tuples #-}
{-# INLINE tolist #-}
pprint (A l t) =
"├ " ++ show l ++ aux 0 t
where
rep i = concat $ replicate i "│ "
bmp f v =
map f $
VF.bitmap v
aux i (L fv) =
"\n" ++ rep i ++ "├ " ++ bmp (\x -> if x then '■' else '▭') fv
aux i (N fv) =
"\n" ++ rep i ++ "├ " ++ bmp (\x -> if x then '▣' else '□') fv ++ sub
where
sub = concat $ map (aux (i+1) . snd) $ VF.tuples fv
tuples (A _ t) =
helper [] t
tolist (A _ t) =
map snd $ helper [] t
--------------------------------------------------------------------------------
amount :: AL256 a -> Integer
sparse :: AL256 a -> Rational
defrag :: AL256 a -> AL256 a
sliver
:: Integer
-> Integer
-> AL256 a
-> AL256 a
expand :: Integer -> AL256 a -> AL256 a
reduce :: Integer -> AL256 a -> AL256 a
{-# INLINE amount #-}
{-# INLINE sparse #-}
{-# INLINE defrag #-}
{-# INLINE sliver #-}
{-# INLINE expand #-}
{-# INLINE reduce #-}
amount (A _ t) =
aux t
where
aux (L fv) = VF.amount fv
aux (N fv) =
if 0 == VF.amount fv
then 0
else foldl' (+) 0 $ map (aux . snd) $ VF.tuples fv
sparse (A 0 _) = 0
sparse al@(A l _) = amount al % l
defrag al =
-- Reduces the degree of fragmentation. Check sparsity first
foldl (\a (i,x) -> update i x a) (create n) $
zip [ 0 .. ] $
tolist al
where
n = amount al
{-| * Length can be read in O(1). Devs responsability to call inside bounds
* Index + offset must be: i+o<=l. Devs responsability to call inside bounds
-}
sliver i o al@(A l _) =
assert (i + o <= l) msg
foldl (\a (j,x) -> update (j-i) x a) (create o) $
takeWhile ((i + o >) . fst) $
dropWhile ((i >) . fst) $
tuples al
where
msg =
"Index i+o (" ++ show (i+o) ++
") must be less or equal to l (" ++ show l ++
")"
{-| Length can be read in O(1). Devs responsability to call inside bounds
-}
expand n (A l t) =
assert (n > l) msg
A n $ aux $ log256 n
where
msg =
"New length " ++ show n ++ " must be greater than previous " ++ show l
aux i
| i > lvl = N $ VF.update 0 (aux $ i - 1) VF.create
| otherwise = t
lvl = log256 l
{-| Length can be read in O(1). Devs responsability to call inside bounds
-}
reduce n al@(A l _) =
assert (n < l) msg
sliver 0 n al
where
msg =
"New length " ++ show n ++ " must be less than previous " ++ show l
--------------------------------------------------------------------------------
-- HELPERS
helper
:: [Integer]
-> Tree a
-> [(Integer, a)]
{-# INLINE helper #-}
helper ns (L fv) =
map (\(i,a) -> (fromIntegral i + (aux lograt ns), a)) $
VF.tuples fv
where
aux _ [ ] = 0
aux i (x:xs) = (1 .<. i) * x + (aux (i + lograt) xs)
helper ns (N fv) =
concat $
map (\(i,x) -> helper (fromIntegral i:ns) x) $
VF.tuples fv
--------------------------------------------------------------------------------
assert
:: Bool
-> String
-> a
-> a
{-# INLINE assert #-}
assert True ___ a = a
assert False msg _ = error msg
--------------------------------------------------------------------------------
branch
:: Int
-> Tree a
vacant
:: Tree a
-> Bool
{-# INLINE branch #-}
{-# INLINE vacant #-}
branch 0 = L VF.create
branch _ = N VF.create
vacant (L fv) = VF.amount fv == 0
vacant (N fv) = VF.amount fv == 0
--------------------------------------------------------------------------------
(.<.)
:: Bits a
=> a
-> Int
-> a
(.>.)
:: Bits a
=> a
-> Int
-> a
{-# INLINE (.<.) #-}
{-# INLINE (.>.) #-}
(.<.) = shiftL
(.>.) = shiftR
--------------------------------------------------------------------------------
lograt
:: Int
logmod
:: Num a
=> a
loglvl
:: Integer
-> Int
i2wrd8
:: Integral a
=> a
-> Word8
{-# INLINE lograt #-}
{-# INLINE logmod #-}
{-# INLINE loglvl #-}
{-# INLINE i2wrd8 #-}
lograt = 0x08
logmod = 0xFF
loglvl = ((*) lograt) . fromIntegral . log256 . (flip (-) 1)
i2wrd8 = fromIntegral
--------------------------------------------------------------------------------
-- http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
--
-- log_{2^b} n ≈ m (floor)
log02b
::
( Bits a
, Num a
)
=> Int
-> a
-> a
log256
::
( Bits a
, Num a
)
=> a
-> a
{-# INLINE log02b #-}
{-# INLINE log256 #-}
log02b b n =
aux 0 (n .>. b)
where
aux acc 0 = acc
aux acc x = aux (acc + 1) (x .>. b)
log256 =
log02b lograt
src/Data/Vector/Fixed256.hs
--------------------------------------------------------------------------------
--
-- Data.Vector.Fixed256, (c) 2020 SPISE MISU ApS
--
--------------------------------------------------------------------------------
{-# LANGUAGE Safe #-}
--------------------------------------------------------------------------------
module Data.Vector.Fixed256
( VF256
--
, create
, exists
, lookup
, update
, remove
--
, amount
, bitmap
, pprint
, tuples
, tolist
) where
--------------------------------------------------------------------------------
import Prelude hiding
( lookup
)
import Data.Bits
( Bits
, clearBit
, popCount
, setBit
, testBit
, (.&.)
)
import Data.Word
( Word64
, Word8
)
--------------------------------------------------------------------------------
data VF256 a = VF
{ bm0 :: !Word64
, bm1 :: !Word64
, bm2 :: !Word64
, bm3 :: !Word64
, i00 :: a, i01 :: a, i02 :: a, i03 :: a
, i04 :: a, i05 :: a, i06 :: a, i07 :: a
, i08 :: a, i09 :: a, i0A :: a, i0B :: a
, i0C :: a, i0D :: a, i0E :: a, i0F :: a
, i10 :: a, i11 :: a, i12 :: a, i13 :: a
, i14 :: a, i15 :: a, i16 :: a, i17 :: a
, i18 :: a, i19 :: a, i1A :: a, i1B :: a
, i1C :: a, i1D :: a, i1E :: a, i1F :: a
, i20 :: a, i21 :: a, i22 :: a, i23 :: a
, i24 :: a, i25 :: a, i26 :: a, i27 :: a
, i28 :: a, i29 :: a, i2A :: a, i2B :: a
, i2C :: a, i2D :: a, i2E :: a, i2F :: a
, i30 :: a, i31 :: a, i32 :: a, i33 :: a
, i34 :: a, i35 :: a, i36 :: a, i37 :: a
, i38 :: a, i39 :: a, i3A :: a, i3B :: a
, i3C :: a, i3D :: a, i3E :: a, i3F :: a
, i40 :: a, i41 :: a, i42 :: a, i43 :: a
, i44 :: a, i45 :: a, i46 :: a, i47 :: a
, i48 :: a, i49 :: a, i4A :: a, i4B :: a
, i4C :: a, i4D :: a, i4E :: a, i4F :: a
, i50 :: a, i51 :: a, i52 :: a, i53 :: a
, i54 :: a, i55 :: a, i56 :: a, i57 :: a
, i58 :: a, i59 :: a, i5A :: a, i5B :: a
, i5C :: a, i5D :: a, i5E :: a, i5F :: a
, i60 :: a, i61 :: a, i62 :: a, i63 :: a
, i64 :: a, i65 :: a, i66 :: a, i67 :: a
, i68 :: a, i69 :: a, i6A :: a, i6B :: a
, i6C :: a, i6D :: a, i6E :: a, i6F :: a
, i70 :: a, i71 :: a, i72 :: a, i73 :: a
, i74 :: a, i75 :: a, i76 :: a, i77 :: a
, i78 :: a, i79 :: a, i7A :: a, i7B :: a
, i7C :: a, i7D :: a, i7E :: a, i7F :: a
, i80 :: a, i81 :: a, i82 :: a, i83 :: a
, i84 :: a, i85 :: a, i86 :: a, i87 :: a
, i88 :: a, i89 :: a, i8A :: a, i8B :: a
, i8C :: a, i8D :: a, i8E :: a, i8F :: a
, i90 :: a, i91 :: a, i92 :: a, i93 :: a
, i94 :: a, i95 :: a, i96 :: a, i97 :: a
, i98 :: a, i99 :: a, i9A :: a, i9B :: a
, i9C :: a, i9D :: a, i9E :: a, i9F :: a
, iA0 :: a, iA1 :: a, iA2 :: a, iA3 :: a
, iA4 :: a, iA5 :: a, iA6 :: a, iA7 :: a
, iA8 :: a, iA9 :: a, iAA :: a, iAB :: a
, iAC :: a, iAD :: a, iAE :: a, iAF :: a
, iB0 :: a, iB1 :: a, iB2 :: a, iB3 :: a
, iB4 :: a, iB5 :: a, iB6 :: a, iB7 :: a
, iB8 :: a, iB9 :: a, iBA :: a, iBB :: a
, iBC :: a, iBD :: a, iBE :: a, iBF :: a
, iC0 :: a, iC1 :: a, iC2 :: a, iC3 :: a
, iC4 :: a, iC5 :: a, iC6 :: a, iC7 :: a
, iC8 :: a, iC9 :: a, iCA :: a, iCB :: a
, iCC :: a, iCD :: a, iCE :: a, iCF :: a
, iD0 :: a, iD1 :: a, iD2 :: a, iD3 :: a
, iD4 :: a, iD5 :: a, iD6 :: a, iD7 :: a
, iD8 :: a, iD9 :: a, iDA :: a, iDB :: a
, iDC :: a, iDD :: a, iDE :: a, iDF :: a
, iE0 :: a, iE1 :: a, iE2 :: a, iE3 :: a
, iE4 :: a, iE5 :: a, iE6 :: a, iE7 :: a
, iE8 :: a, iE9 :: a, iEA :: a, iEB :: a
, iEC :: a, iED :: a, iEE :: a, iEF :: a
, iF0 :: a, iF1 :: a, iF2 :: a, iF3 :: a
, iF4 :: a, iF5 :: a, iF6 :: a, iF7 :: a
, iF8 :: a, iF9 :: a, iFA :: a, iFB :: a
, iFC :: a, iFD :: a, iFE :: a, iFF :: a
}
instance Show a => Show (VF256 a) where
show = show . tuples
instance Foldable VF256 where
foldMap f =
foldMap f .
tolist
instance Functor VF256 where
fmap f =
foldl (\ a (i,x) -> update i x a) create .
fmap (\ (i,x) -> (i,f x )) .
tuples
--------------------------------------------------------------------------------
create
:: VF256 a
exists
:: Word8
-> VF256 a
-> Bool
lookup
:: Word8
-> VF256 a
-> a
update
:: Word8
-> a
-> VF256 a
-> VF256 a
remove
:: Word8
-> VF256 a
-> VF256 a
{-# INLINE create #-}
{-# INLINE exists #-}
{-# INLINE lookup #-}
{-# INLINE update #-}
{-# INLINE remove #-}
--------------------------------------------------------------------------------
amount
:: VF256 a
-> Integer
bitmap
:: VF256 a
-> [ Bool ]
pprint
:: VF256 a
-> String
tuples
:: VF256 a
-> [ (Word8, a) ]
tolist
:: VF256 a
-> [a]
{-# INLINE amount #-}
{-# INLINE bitmap #-}
{-# INLINE pprint #-}
{-# INLINE tuples #-}
{-# INLINE tolist #-}
--------------------------------------------------------------------------------
create =
VF
0 0 0 0
b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b
where
b = undefined -- ⊥
exists i vf =
bmp `seq` j `seq` bmp .?. j
where
(bmp,j)
| i < 064 = (bm0 vf, fromIntegral i )
| i < 128 = (bm1 vf, fromIntegral (i .&. 63))
| i < 192 = (bm2 vf, fromIntegral (i .&. 63))
| otherwise = (bm3 vf, fromIntegral (i .&. 63))
lookup i vf =
case i of
000 -> i00 vf
001 -> i01 vf
002 -> i02 vf
003 -> i03 vf
004 -> i04 vf
005 -> i05 vf
006 -> i06 vf
007 -> i07 vf
008 -> i08 vf
009 -> i09 vf
010 -> i0A vf
011 -> i0B vf
012 -> i0C vf
013 -> i0D vf
014 -> i0E vf
015 -> i0F vf
016 -> i10 vf
017 -> i11 vf
018 -> i12 vf
019 -> i13 vf
020 -> i14 vf
021 -> i15 vf
022 -> i16 vf
023 -> i17 vf
024 -> i18 vf
025 -> i19 vf
026 -> i1A vf
027 -> i1B vf
028 -> i1C vf
029 -> i1D vf
030 -> i1E vf
031 -> i1F vf
032 -> i20 vf
033 -> i21 vf
034 -> i22 vf
035 -> i23 vf
036 -> i24 vf
037 -> i25 vf
038 -> i26 vf
039 -> i27 vf
040 -> i28 vf
041 -> i29 vf
042 -> i2A vf
043 -> i2B vf
044 -> i2C vf
045 -> i2D vf
046 -> i2E vf
047 -> i2F vf
048 -> i30 vf
049 -> i31 vf
050 -> i32 vf
051 -> i33 vf
052 -> i34 vf
053 -> i35 vf
054 -> i36 vf
055 -> i37 vf
056 -> i38 vf
057 -> i39 vf
058 -> i3A vf
059 -> i3B vf
060 -> i3C vf
061 -> i3D vf
062 -> i3E vf
063 -> i3F vf
064 -> i40 vf
065 -> i41 vf
066 -> i42 vf
067 -> i43 vf
068 -> i44 vf
069 -> i45 vf
070 -> i46 vf
071 -> i47 vf
072 -> i48 vf
073 -> i49 vf
074 -> i4A vf
075 -> i4B vf
076 -> i4C vf
077 -> i4D vf
078 -> i4E vf
079 -> i4F vf
080 -> i50 vf
081 -> i51 vf
082 -> i52 vf
083 -> i53 vf
084 -> i54 vf
085 -> i55 vf
086 -> i56 vf
087 -> i57 vf
088 -> i58 vf
089 -> i59 vf
090 -> i5A vf
091 -> i5B vf
092 -> i5C vf
093 -> i5D vf
094 -> i5E vf
095 -> i5F vf
096 -> i60 vf
097 -> i61 vf
098 -> i62 vf
099 -> i63 vf
100 -> i64 vf
101 -> i65 vf
102 -> i66 vf
103 -> i67 vf
104 -> i68 vf
105 -> i69 vf
106 -> i6A vf
107 -> i6B vf
108 -> i6C vf
109 -> i6D vf
110 -> i6E vf
111 -> i6F vf
112 -> i70 vf
113 -> i71 vf
114 -> i72 vf
115 -> i73 vf
116 -> i74 vf
117 -> i75 vf
118 -> i76 vf
119 -> i77 vf
120 -> i78 vf
121 -> i79 vf
122 -> i7A vf
123 -> i7B vf
124 -> i7C vf
125 -> i7D vf
126 -> i7E vf
127 -> i7F vf
128 -> i80 vf
129 -> i81 vf
130 -> i82 vf
131 -> i83 vf
132 -> i84 vf
133 -> i85 vf
134 -> i86 vf
135 -> i87 vf
136 -> i88 vf
137 -> i89 vf
138 -> i8A vf
139 -> i8B vf
140 -> i8C vf
141 -> i8D vf
142 -> i8E vf
143 -> i8F vf
144 -> i90 vf
145 -> i91 vf
146 -> i92 vf
147 -> i93 vf
148 -> i94 vf
149 -> i95 vf
150 -> i96 vf
151 -> i97 vf
152 -> i98 vf
153 -> i99 vf
154 -> i9A vf
155 -> i9B vf
156 -> i9C vf
157 -> i9D vf
158 -> i9E vf
159 -> i9F vf
160 -> iA0 vf
161 -> iA1 vf
162 -> iA2 vf
163 -> iA3 vf
164 -> iA4 vf
165 -> iA5 vf
166 -> iA6 vf
167 -> iA7 vf
168 -> iA8 vf
169 -> iA9 vf
170 -> iAA vf
171 -> iAB vf
172 -> iAC vf
173 -> iAD vf
174 -> iAE vf
175 -> iAF vf
176 -> iB0 vf
177 -> iB1 vf
178 -> iB2 vf
179 -> iB3 vf
180 -> iB4 vf
181 -> iB5 vf
182 -> iB6 vf
183 -> iB7 vf
184 -> iB8 vf
185 -> iB9 vf
186 -> iBA vf
187 -> iBB vf
188 -> iBC vf
189 -> iBD vf
190 -> iBE vf
191 -> iBF vf
192 -> iC0 vf
193 -> iC1 vf
194 -> iC2 vf
195 -> iC3 vf
196 -> iC4 vf
197 -> iC5 vf
198 -> iC6 vf
199 -> iC7 vf
200 -> iC8 vf
201 -> iC9 vf
202 -> iCA vf
203 -> iCB vf
204 -> iCC vf
205 -> iCD vf
206 -> iCE vf
207 -> iCF vf
208 -> iD0 vf
209 -> iD1 vf
210 -> iD2 vf
211 -> iD3 vf
212 -> iD4 vf
213 -> iD5 vf
214 -> iD6 vf
215 -> iD7 vf
216 -> iD8 vf
217 -> iD9 vf
218 -> iDA vf
219 -> iDB vf
220 -> iDC vf
221 -> iDD vf
222 -> iDE vf
223 -> iDF vf
224 -> iE0 vf
225 -> iE1 vf
226 -> iE2 vf
227 -> iE3 vf
228 -> iE4 vf
229 -> iE5 vf
230 -> iE6 vf
231 -> iE7 vf
232 -> iE8 vf
233 -> iE9 vf
234 -> iEA vf
235 -> iEB vf
236 -> iEC vf
237 -> iED vf
238 -> iEE vf
239 -> iEF vf
240 -> iF0 vf
241 -> iF1 vf
242 -> iF2 vf
243 -> iF3 vf
244 -> iF4 vf
245 -> iF5 vf
246 -> iF6 vf
247 -> iF7 vf
248 -> iF8 vf
249 -> iF9 vf
250 -> iFA vf
251 -> iFB vf
252 -> iFC vf
253 -> iFD vf
254 -> iFE vf
255 -> iFF vf
___ -> undefined -- Literal is out of Word8 range
update i a vf =
case i of
000 -> vf { bm0 = bm0 vf .■. 00, i00 = a }
001 -> vf { bm0 = bm0 vf .■. 01, i01 = a }
002 -> vf { bm0 = bm0 vf .■. 02, i02 = a }
003 -> vf { bm0 = bm0 vf .■. 03, i03 = a }
004 -> vf { bm0 = bm0 vf .■. 04, i04 = a }
005 -> vf { bm0 = bm0 vf .■. 05, i05 = a }
006 -> vf { bm0 = bm0 vf .■. 06, i06 = a }
007 -> vf { bm0 = bm0 vf .■. 07, i07 = a }
008 -> vf { bm0 = bm0 vf .■. 08, i08 = a }
009 -> vf { bm0 = bm0 vf .■. 09, i09 = a }
010 -> vf { bm0 = bm0 vf .■. 10, i0A = a }
011 -> vf { bm0 = bm0 vf .■. 11, i0B = a }
012 -> vf { bm0 = bm0 vf .■. 12, i0C = a }
013 -> vf { bm0 = bm0 vf .■. 13, i0D = a }
014 -> vf { bm0 = bm0 vf .■. 14, i0E = a }
015 -> vf { bm0 = bm0 vf .■. 15, i0F = a }
016 -> vf { bm0 = bm0 vf .■. 16, i10 = a }
017 -> vf { bm0 = bm0 vf .■. 17, i11 = a }
018 -> vf { bm0 = bm0 vf .■. 18, i12 = a }
019 -> vf { bm0 = bm0 vf .■. 19, i13 = a }
020 -> vf { bm0 = bm0 vf .■. 20, i14 = a }
021 -> vf { bm0 = bm0 vf .■. 21, i15 = a }
022 -> vf { bm0 = bm0 vf .■. 22, i16 = a }
023 -> vf { bm0 = bm0 vf .■. 23, i17 = a }
024 -> vf { bm0 = bm0 vf .■. 24, i18 = a }
025 -> vf { bm0 = bm0 vf .■. 25, i19 = a }
026 -> vf { bm0 = bm0 vf .■. 26, i1A = a }
027 -> vf { bm0 = bm0 vf .■. 27, i1B = a }
028 -> vf { bm0 = bm0 vf .■. 28, i1C = a }
029 -> vf { bm0 = bm0 vf .■. 29, i1D = a }
030 -> vf { bm0 = bm0 vf .■. 30, i1E = a }
031 -> vf { bm0 = bm0 vf .■. 31, i1F = a }
032 -> vf { bm0 = bm0 vf .■. 32, i20 = a }
033 -> vf { bm0 = bm0 vf .■. 33, i21 = a }
034 -> vf { bm0 = bm0 vf .■. 34, i22 = a }
035 -> vf { bm0 = bm0 vf .■. 35, i23 = a }
036 -> vf { bm0 = bm0 vf .■. 36, i24 = a }
037 -> vf { bm0 = bm0 vf .■. 37, i25 = a }
038 -> vf { bm0 = bm0 vf .■. 38, i26 = a }
039 -> vf { bm0 = bm0 vf .■. 39, i27 = a }
040 -> vf { bm0 = bm0 vf .■. 40, i28 = a }
041 -> vf { bm0 = bm0 vf .■. 41, i29 = a }
042 -> vf { bm0 = bm0 vf .■. 42, i2A = a }
043 -> vf { bm0 = bm0 vf .■. 43, i2B = a }
044 -> vf { bm0 = bm0 vf .■. 44, i2C = a }
045 -> vf { bm0 = bm0 vf .■. 45, i2D = a }
046 -> vf { bm0 = bm0 vf .■. 46, i2E = a }
047 -> vf { bm0 = bm0 vf .■. 47, i2F = a }
048 -> vf { bm0 = bm0 vf .■. 48, i30 = a }
049 -> vf { bm0 = bm0 vf .■. 49, i31 = a }
050 -> vf { bm0 = bm0 vf .■. 50, i32 = a }
051 -> vf { bm0 = bm0 vf .■. 51, i33 = a }
052 -> vf { bm0 = bm0 vf .■. 52, i34 = a }
053 -> vf { bm0 = bm0 vf .■. 53, i35 = a }
054 -> vf { bm0 = bm0 vf .■. 54, i36 = a }
055 -> vf { bm0 = bm0 vf .■. 55, i37 = a }
056 -> vf { bm0 = bm0 vf .■. 56, i38 = a }
057 -> vf { bm0 = bm0 vf .■. 57, i39 = a }
058 -> vf { bm0 = bm0 vf .■. 58, i3A = a }
059 -> vf { bm0 = bm0 vf .■. 59, i3B = a }
060 -> vf { bm0 = bm0 vf .■. 60, i3C = a }
061 -> vf { bm0 = bm0 vf .■. 61, i3D = a }
062 -> vf { bm0 = bm0 vf .■. 62, i3E = a }
063 -> vf { bm0 = bm0 vf .■. 63, i3F = a }
064 -> vf { bm1 = bm1 vf .■. 00, i40 = a }
065 -> vf { bm1 = bm1 vf .■. 01, i41 = a }
066 -> vf { bm1 = bm1 vf .■. 02, i42 = a }
067 -> vf { bm1 = bm1 vf .■. 03, i43 = a }
068 -> vf { bm1 = bm1 vf .■. 04, i44 = a }
069 -> vf { bm1 = bm1 vf .■. 05, i45 = a }
070 -> vf { bm1 = bm1 vf .■. 06, i46 = a }
071 -> vf { bm1 = bm1 vf .■. 07, i47 = a }
072 -> vf { bm1 = bm1 vf .■. 08, i48 = a }
073 -> vf { bm1 = bm1 vf .■. 09, i49 = a }
074 -> vf { bm1 = bm1 vf .■. 10, i4A = a }
075 -> vf { bm1 = bm1 vf .■. 11, i4B = a }
076 -> vf { bm1 = bm1 vf .■. 12, i4C = a }
077 -> vf { bm1 = bm1 vf .■. 13, i4D = a }
078 -> vf { bm1 = bm1 vf .■. 14, i4E = a }
079 -> vf { bm1 = bm1 vf .■. 15, i4F = a }
080 -> vf { bm1 = bm1 vf .■. 16, i50 = a }
081 -> vf { bm1 = bm1 vf .■. 17, i51 = a }
082 -> vf { bm1 = bm1 vf .■. 18, i52 = a }
083 -> vf { bm1 = bm1 vf .■. 19, i53 = a }
084 -> vf { bm1 = bm1 vf .■. 20, i54 = a }
085 -> vf { bm1 = bm1 vf .■. 21, i55 = a }
086 -> vf { bm1 = bm1 vf .■. 22, i56 = a }
087 -> vf { bm1 = bm1 vf .■. 23, i57 = a }
088 -> vf { bm1 = bm1 vf .■. 24, i58 = a }
089 -> vf { bm1 = bm1 vf .■. 25, i59 = a }
090 -> vf { bm1 = bm1 vf .■. 26, i5A = a }
091 -> vf { bm1 = bm1 vf .■. 27, i5B = a }
092 -> vf { bm1 = bm1 vf .■. 28, i5C = a }
093 -> vf { bm1 = bm1 vf .■. 29, i5D = a }
094 -> vf { bm1 = bm1 vf .■. 30, i5E = a }
095 -> vf { bm1 = bm1 vf .■. 31, i5F = a }
096 -> vf { bm1 = bm1 vf .■. 32, i60 = a }
097 -> vf { bm1 = bm1 vf .■. 33, i61 = a }
098 -> vf { bm1 = bm1 vf .■. 34, i62 = a }
099 -> vf { bm1 = bm1 vf .■. 35, i63 = a }
100 -> vf { bm1 = bm1 vf .■. 36, i64 = a }
101 -> vf { bm1 = bm1 vf .■. 37, i65 = a }
102 -> vf { bm1 = bm1 vf .■. 38, i66 = a }
103 -> vf { bm1 = bm1 vf .■. 39, i67 = a }
104 -> vf { bm1 = bm1 vf .■. 40, i68 = a }
105 -> vf { bm1 = bm1 vf .■. 41, i69 = a }
106 -> vf { bm1 = bm1 vf .■. 42, i6A = a }
107 -> vf { bm1 = bm1 vf .■. 43, i6B = a }
108 -> vf { bm1 = bm1 vf .■. 44, i6C = a }
109 -> vf { bm1 = bm1 vf .■. 45, i6D = a }
110 -> vf { bm1 = bm1 vf .■. 46, i6E = a }
111 -> vf { bm1 = bm1 vf .■. 47, i6F = a }
112 -> vf { bm1 = bm1 vf .■. 48, i70 = a }
113 -> vf { bm1 = bm1 vf .■. 49, i71 = a }
114 -> vf { bm1 = bm1 vf .■. 50, i72 = a }
115 -> vf { bm1 = bm1 vf .■. 51, i73 = a }
116 -> vf { bm1 = bm1 vf .■. 52, i74 = a }
117 -> vf { bm1 = bm1 vf .■. 53, i75 = a }
118 -> vf { bm1 = bm1 vf .■. 54, i76 = a }
119 -> vf { bm1 = bm1 vf .■. 55, i77 = a }
120 -> vf { bm1 = bm1 vf .■. 56, i78 = a }
121 -> vf { bm1 = bm1 vf .■. 57, i79 = a }
122 -> vf { bm1 = bm1 vf .■. 58, i7A = a }
123 -> vf { bm1 = bm1 vf .■. 59, i7B = a }
124 -> vf { bm1 = bm1 vf .■. 60, i7C = a }
125 -> vf { bm1 = bm1 vf .■. 61, i7D = a }
126 -> vf { bm1 = bm1 vf .■. 62, i7E = a }
127 -> vf { bm1 = bm1 vf .■. 63, i7F = a }
128 -> vf { bm2 = bm2 vf .■. 00, i80 = a }
129 -> vf { bm2 = bm2 vf .■. 01, i81 = a }
130 -> vf { bm2 = bm2 vf .■. 02, i82 = a }
131 -> vf { bm2 = bm2 vf .■. 03, i83 = a }
132 -> vf { bm2 = bm2 vf .■. 04, i84 = a }
133 -> vf { bm2 = bm2 vf .■. 05, i85 = a }
134 -> vf { bm2 = bm2 vf .■. 06, i86 = a }
135 -> vf { bm2 = bm2 vf .■. 07, i87 = a }
136 -> vf { bm2 = bm2 vf .■. 08, i88 = a }
137 -> vf { bm2 = bm2 vf .■. 09, i89 = a }
138 -> vf { bm2 = bm2 vf .■. 10, i8A = a }
139 -> vf { bm2 = bm2 vf .■. 11, i8B = a }
140 -> vf { bm2 = bm2 vf .■. 12, i8C = a }
141 -> vf { bm2 = bm2 vf .■. 13, i8D = a }
142 -> vf { bm2 = bm2 vf .■. 14, i8E = a }
143 -> vf { bm2 = bm2 vf .■. 15, i8F = a }
144 -> vf { bm2 = bm2 vf .■. 16, i90 = a }
145 -> vf { bm2 = bm2 vf .■. 17, i91 = a }
146 -> vf { bm2 = bm2 vf .■. 18, i92 = a }
147 -> vf { bm2 = bm2 vf .■. 19, i93 = a }
148 -> vf { bm2 = bm2 vf .■. 20, i94 = a }
149 -> vf { bm2 = bm2 vf .■. 21, i95 = a }
150 -> vf { bm2 = bm2 vf .■. 22, i96 = a }
151 -> vf { bm2 = bm2 vf .■. 23, i97 = a }
152 -> vf { bm2 = bm2 vf .■. 24, i98 = a }
153 -> vf { bm2 = bm2 vf .■. 25, i99 = a }
154 -> vf { bm2 = bm2 vf .■. 26, i9A = a }
155 -> vf { bm2 = bm2 vf .■. 27, i9B = a }
156 -> vf { bm2 = bm2 vf .■. 28, i9C = a }
157 -> vf { bm2 = bm2 vf .■. 29, i9D = a }
158 -> vf { bm2 = bm2 vf .■. 30, i9E = a }
159 -> vf { bm2 = bm2 vf .■. 31, i9F = a }
160 -> vf { bm2 = bm2 vf .■. 32, iA0 = a }
161 -> vf { bm2 = bm2 vf .■. 33, iA1 = a }
162 -> vf { bm2 = bm2 vf .■. 34, iA2 = a }
163 -> vf { bm2 = bm2 vf .■. 35, iA3 = a }
164 -> vf { bm2 = bm2 vf .■. 36, iA4 = a }
165 -> vf { bm2 = bm2 vf .■. 37, iA5 = a }
166 -> vf { bm2 = bm2 vf .■. 38, iA6 = a }
167 -> vf { bm2 = bm2 vf .■. 39, iA7 = a }
168 -> vf { bm2 = bm2 vf .■. 40, iA8 = a }
169 -> vf { bm2 = bm2 vf .■. 41, iA9 = a }
170 -> vf { bm2 = bm2 vf .■. 42, iAA = a }
171 -> vf { bm2 = bm2 vf .■. 43, iAB = a }
172 -> vf { bm2 = bm2 vf .■. 44, iAC = a }
173 -> vf { bm2 = bm2 vf .■. 45, iAD = a }
174 -> vf { bm2 = bm2 vf .■. 46, iAE = a }
175 -> vf { bm2 = bm2 vf .■. 47, iAF = a }
176 -> vf { bm2 = bm2 vf .■. 48, iB0 = a }
177 -> vf { bm2 = bm2 vf .■. 49, iB1 = a }
178 -> vf { bm2 = bm2 vf .■. 50, iB2 = a }
179 -> vf { bm2 = bm2 vf .■. 51, iB3 = a }
180 -> vf { bm2 = bm2 vf .■. 52, iB4 = a }
181 -> vf { bm2 = bm2 vf .■. 53, iB5 = a }
182 -> vf { bm2 = bm2 vf .■. 54, iB6 = a }
183 -> vf { bm2 = bm2 vf .■. 55, iB7 = a }
184 -> vf { bm2 = bm2 vf .■. 56, iB8 = a }
185 -> vf { bm2 = bm2 vf .■. 57, iB9 = a }
186 -> vf { bm2 = bm2 vf .■. 58, iBA = a }
187 -> vf { bm2 = bm2 vf .■. 59, iBB = a }
188 -> vf { bm2 = bm2 vf .■. 60, iBC = a }
189 -> vf { bm2 = bm2 vf .■. 61, iBD = a }
190 -> vf { bm2 = bm2 vf .■. 62, iBE = a }
191 -> vf { bm2 = bm2 vf .■. 63, iBF = a }
192 -> vf { bm3 = bm3 vf .■. 00, iC0 = a }
193 -> vf { bm3 = bm3 vf .■. 01, iC1 = a }
194 -> vf { bm3 = bm3 vf .■. 02, iC2 = a }
195 -> vf { bm3 = bm3 vf .■. 03, iC3 = a }
196 -> vf { bm3 = bm3 vf .■. 04, iC4 = a }
197 -> vf { bm3 = bm3 vf .■. 05, iC5 = a }
198 -> vf { bm3 = bm3 vf .■. 06, iC6 = a }
199 -> vf { bm3 = bm3 vf .■. 07, iC7 = a }
200 -> vf { bm3 = bm3 vf .■. 08, iC8 = a }
201 -> vf { bm3 = bm3 vf .■. 09, iC9 = a }
202 -> vf { bm3 = bm3 vf .■. 10, iCA = a }
203 -> vf { bm3 = bm3 vf .■. 11, iCB = a }
204 -> vf { bm3 = bm3 vf .■. 12, iCC = a }
205 -> vf { bm3 = bm3 vf .■. 13, iCD = a }
206 -> vf { bm3 = bm3 vf .■. 14, iCE = a }
207 -> vf { bm3 = bm3 vf .■. 15, iCF = a }
208 -> vf { bm3 = bm3 vf .■. 16, iD0 = a }
209 -> vf { bm3 = bm3 vf .■. 17, iD1 = a }
210 -> vf { bm3 = bm3 vf .■. 18, iD2 = a }
211 -> vf { bm3 = bm3 vf .■. 19, iD3 = a }
212 -> vf { bm3 = bm3 vf .■. 20, iD4 = a }
213 -> vf { bm3 = bm3 vf .■. 21, iD5 = a }
214 -> vf { bm3 = bm3 vf .■. 22, iD6 = a }
215 -> vf { bm3 = bm3 vf .■. 23, iD7 = a }
216 -> vf { bm3 = bm3 vf .■. 24, iD8 = a }
217 -> vf { bm3 = bm3 vf .■. 25, iD9 = a }
218 -> vf { bm3 = bm3 vf .■. 26, iDA = a }
219 -> vf { bm3 = bm3 vf .■. 27, iDB = a }
220 -> vf { bm3 = bm3 vf .■. 28, iDC = a }
221 -> vf { bm3 = bm3 vf .■. 29, iDD = a }
222 -> vf { bm3 = bm3 vf .■. 30, iDE = a }
223 -> vf { bm3 = bm3 vf .■. 31, iDF = a }
224 -> vf { bm3 = bm3 vf .■. 32, iE0 = a }
225 -> vf { bm3 = bm3 vf .■. 33, iE1 = a }
226 -> vf { bm3 = bm3 vf .■. 34, iE2 = a }
227 -> vf { bm3 = bm3 vf .■. 35, iE3 = a }
228 -> vf { bm3 = bm3 vf .■. 36, iE4 = a }
229 -> vf { bm3 = bm3 vf .■. 37, iE5 = a }
230 -> vf { bm3 = bm3 vf .■. 38, iE6 = a }
231 -> vf { bm3 = bm3 vf .■. 39, iE7 = a }
232 -> vf { bm3 = bm3 vf .■. 40, iE8 = a }
233 -> vf { bm3 = bm3 vf .■. 41, iE9 = a }
234 -> vf { bm3 = bm3 vf .■. 42, iEA = a }
235 -> vf { bm3 = bm3 vf .■. 43, iEB = a }
236 -> vf { bm3 = bm3 vf .■. 44, iEC = a }
237 -> vf { bm3 = bm3 vf .■. 45, iED = a }
238 -> vf { bm3 = bm3 vf .■. 46, iEE = a }
239 -> vf { bm3 = bm3 vf .■. 47, iEF = a }
240 -> vf { bm3 = bm3 vf .■. 48, iF0 = a }
241 -> vf { bm3 = bm3 vf .■. 49, iF1 = a }
242 -> vf { bm3 = bm3 vf .■. 50, iF2 = a }
243 -> vf { bm3 = bm3 vf .■. 51, iF3 = a }
244 -> vf { bm3 = bm3 vf .■. 52, iF4 = a }
245 -> vf { bm3 = bm3 vf .■. 53, iF5 = a }
246 -> vf { bm3 = bm3 vf .■. 54, iF6 = a }
247 -> vf { bm3 = bm3 vf .■. 55, iF7 = a }
248 -> vf { bm3 = bm3 vf .■. 56, iF8 = a }
249 -> vf { bm3 = bm3 vf .■. 57, iF9 = a }
250 -> vf { bm3 = bm3 vf .■. 58, iFA = a }
251 -> vf { bm3 = bm3 vf .■. 59, iFB = a }
252 -> vf { bm3 = bm3 vf .■. 60, iFC = a }
253 -> vf { bm3 = bm3 vf .■. 61, iFD = a }
254 -> vf { bm3 = bm3 vf .■. 62, iFE = a }
255 -> vf { bm3 = bm3 vf .■. 63, iFF = a }
___ -> undefined -- Literal is out of Word8 range
remove i vf =
case i of
000 -> vf { bm0 = bm0 vf .□. 00, i00 = b }
001 -> vf { bm0 = bm0 vf .□. 01, i01 = b }
002 -> vf { bm0 = bm0 vf .□. 02, i02 = b }
003 -> vf { bm0 = bm0 vf .□. 03, i03 = b }
004 -> vf { bm0 = bm0 vf .□. 04, i04 = b }
005 -> vf { bm0 = bm0 vf .□. 05, i05 = b }
006 -> vf { bm0 = bm0 vf .□. 06, i06 = b }
007 -> vf { bm0 = bm0 vf .□. 07, i07 = b }
008 -> vf { bm0 = bm0 vf .□. 08, i08 = b }
009 -> vf { bm0 = bm0 vf .□. 09, i09 = b }
010 -> vf { bm0 = bm0 vf .□. 10, i0A = b }
011 -> vf { bm0 = bm0 vf .□. 11, i0B = b }
012 -> vf { bm0 = bm0 vf .□. 12, i0C = b }
013 -> vf { bm0 = bm0 vf .□. 13, i0D = b }
014 -> vf { bm0 = bm0 vf .□. 14, i0E = b }
015 -> vf { bm0 = bm0 vf .□. 15, i0F = b }
016 -> vf { bm0 = bm0 vf .□. 16, i10 = b }
017 -> vf { bm0 = bm0 vf .□. 17, i11 = b }
018 -> vf { bm0 = bm0 vf .□. 18, i12 = b }
019 -> vf { bm0 = bm0 vf .□. 19, i13 = b }
020 -> vf { bm0 = bm0 vf .□. 20, i14 = b }
021 -> vf { bm0 = bm0 vf .□. 21, i15 = b }
022 -> vf { bm0 = bm0 vf .□. 22, i16 = b }
023 -> vf { bm0 = bm0 vf .□. 23, i17 = b }
024 -> vf { bm0 = bm0 vf .□. 24, i18 = b }
025 -> vf { bm0 = bm0 vf .□. 25, i19 = b }
026 -> vf { bm0 = bm0 vf .□. 26, i1A = b }
027 -> vf { bm0 = bm0 vf .□. 27, i1B = b }
028 -> vf { bm0 = bm0 vf .□. 28, i1C = b }
029 -> vf { bm0 = bm0 vf .□. 29, i1D = b }
030 -> vf { bm0 = bm0 vf .□. 30, i1E = b }
031 -> vf { bm0 = bm0 vf .□. 31, i1F = b }
032 -> vf { bm0 = bm0 vf .□. 32, i20 = b }
033 -> vf { bm0 = bm0 vf .□. 33, i21 = b }
034 -> vf { bm0 = bm0 vf .□. 34, i22 = b }
035 -> vf { bm0 = bm0 vf .□. 35, i23 = b }
036 -> vf { bm0 = bm0 vf .□. 36, i24 = b }
037 -> vf { bm0 = bm0 vf .□. 37, i25 = b }
038 -> vf { bm0 = bm0 vf .□. 38, i26 = b }
039 -> vf { bm0 = bm0 vf .□. 39, i27 = b }
040 -> vf { bm0 = bm0 vf .□. 40, i28 = b }
041 -> vf { bm0 = bm0 vf .□. 41, i29 = b }
042 -> vf { bm0 = bm0 vf .□. 42, i2A = b }
043 -> vf { bm0 = bm0 vf .□. 43, i2B = b }
044 -> vf { bm0 = bm0 vf .□. 44, i2C = b }
045 -> vf { bm0 = bm0 vf .□. 45, i2D = b }
046 -> vf { bm0 = bm0 vf .□. 46, i2E = b }
047 -> vf { bm0 = bm0 vf .□. 47, i2F = b }
048 -> vf { bm0 = bm0 vf .□. 48, i30 = b }
049 -> vf { bm0 = bm0 vf .□. 49, i31 = b }
050 -> vf { bm0 = bm0 vf .□. 50, i32 = b }
051 -> vf { bm0 = bm0 vf .□. 51, i33 = b }
052 -> vf { bm0 = bm0 vf .□. 52, i34 = b }
053 -> vf { bm0 = bm0 vf .□. 53, i35 = b }
054 -> vf { bm0 = bm0 vf .□. 54, i36 = b }
055 -> vf { bm0 = bm0 vf .□. 55, i37 = b }
056 -> vf { bm0 = bm0 vf .□. 56, i38 = b }
057 -> vf { bm0 = bm0 vf .□. 57, i39 = b }
058 -> vf { bm0 = bm0 vf .□. 58, i3A = b }
059 -> vf { bm0 = bm0 vf .□. 59, i3B = b }
060 -> vf { bm0 = bm0 vf .□. 60, i3C = b }
061 -> vf { bm0 = bm0 vf .□. 61, i3D = b }
062 -> vf { bm0 = bm0 vf .□. 62, i3E = b }
063 -> vf { bm0 = bm0 vf .□. 63, i3F = b }
064 -> vf { bm1 = bm1 vf .□. 00, i40 = b }
065 -> vf { bm1 = bm1 vf .□. 01, i41 = b }
066 -> vf { bm1 = bm1 vf .□. 02, i42 = b }
067 -> vf { bm1 = bm1 vf .□. 03, i43 = b }
068 -> vf { bm1 = bm1 vf .□. 04, i44 = b }
069 -> vf { bm1 = bm1 vf .□. 05, i45 = b }
070 -> vf { bm1 = bm1 vf .□. 06, i46 = b }
071 -> vf { bm1 = bm1 vf .□. 07, i47 = b }
072 -> vf { bm1 = bm1 vf .□. 08, i48 = b }
073 -> vf { bm1 = bm1 vf .□. 09, i49 = b }
074 -> vf { bm1 = bm1 vf .□. 10, i4A = b }
075 -> vf { bm1 = bm1 vf .□. 11, i4B = b }
076 -> vf { bm1 = bm1 vf .□. 12, i4C = b }
077 -> vf { bm1 = bm1 vf .□. 13, i4D = b }
078 -> vf { bm1 = bm1 vf .□. 14, i4E = b }
079 -> vf { bm1 = bm1 vf .□. 15, i4F = b }
080 -> vf { bm1 = bm1 vf .□. 16, i50 = b }
081 -> vf { bm1 = bm1 vf .□. 17, i51 = b }
082 -> vf { bm1 = bm1 vf .□. 18, i52 = b }
083 -> vf { bm1 = bm1 vf .□. 19, i53 = b }
084 -> vf { bm1 = bm1 vf .□. 20, i54 = b }
085 -> vf { bm1 = bm1 vf .□. 21, i55 = b }
086 -> vf { bm1 = bm1 vf .□. 22, i56 = b }
087 -> vf { bm1 = bm1 vf .□. 23, i57 = b }
088 -> vf { bm1 = bm1 vf .□. 24, i58 = b }
089 -> vf { bm1 = bm1 vf .□. 25, i59 = b }
090 -> vf { bm1 = bm1 vf .□. 26, i5A = b }
091 -> vf { bm1 = bm1 vf .□. 27, i5B = b }
092 -> vf { bm1 = bm1 vf .□. 28, i5C = b }
093 -> vf { bm1 = bm1 vf .□. 29, i5D = b }
094 -> vf { bm1 = bm1 vf .□. 30, i5E = b }
095 -> vf { bm1 = bm1 vf .□. 31, i5F = b }
096 -> vf { bm1 = bm1 vf .□. 32, i60 = b }
097 -> vf { bm1 = bm1 vf .□. 33, i61 = b }
098 -> vf { bm1 = bm1 vf .□. 34, i62 = b }
099 -> vf { bm1 = bm1 vf .□. 35, i63 = b }
100 -> vf { bm1 = bm1 vf .□. 36, i64 = b }
101 -> vf { bm1 = bm1 vf .□. 37, i65 = b }
102 -> vf { bm1 = bm1 vf .□. 38, i66 = b }
103 -> vf { bm1 = bm1 vf .□. 39, i67 = b }
104 -> vf { bm1 = bm1 vf .□. 40, i68 = b }
105 -> vf { bm1 = bm1 vf .□. 41, i69 = b }
106 -> vf { bm1 = bm1 vf .□. 42, i6A = b }
107 -> vf { bm1 = bm1 vf .□. 43, i6B = b }
108 -> vf { bm1 = bm1 vf .□. 44, i6C = b }
109 -> vf { bm1 = bm1 vf .□. 45, i6D = b }
110 -> vf { bm1 = bm1 vf .□. 46, i6E = b }
111 -> vf { bm1 = bm1 vf .□. 47, i6F = b }
112 -> vf { bm1 = bm1 vf .□. 48, i70 = b }
113 -> vf { bm1 = bm1 vf .□. 49, i71 = b }
114 -> vf { bm1 = bm1 vf .□. 50, i72 = b }
115 -> vf { bm1 = bm1 vf .□. 51, i73 = b }
116 -> vf { bm1 = bm1 vf .□. 52, i74 = b }
117 -> vf { bm1 = bm1 vf .□. 53, i75 = b }
118 -> vf { bm1 = bm1 vf .□. 54, i76 = b }
119 -> vf { bm1 = bm1 vf .□. 55, i77 = b }
120 -> vf { bm1 = bm1 vf .□. 56, i78 = b }
121 -> vf { bm1 = bm1 vf .□. 57, i79 = b }
122 -> vf { bm1 = bm1 vf .□. 58, i7A = b }
123 -> vf { bm1 = bm1 vf .□. 59, i7B = b }
124 -> vf { bm1 = bm1 vf .□. 60, i7C = b }
125 -> vf { bm1 = bm1 vf .□. 61, i7D = b }
126 -> vf { bm1 = bm1 vf .□. 62, i7E = b }
127 -> vf { bm1 = bm1 vf .□. 63, i7F = b }
128 -> vf { bm2 = bm2 vf .□. 00, i80 = b }
129 -> vf { bm2 = bm2 vf .□. 01, i81 = b }
130 -> vf { bm2 = bm2 vf .□. 02, i82 = b }
131 -> vf { bm2 = bm2 vf .□. 03, i83 = b }
132 -> vf { bm2 = bm2 vf .□. 04, i84 = b }
133 -> vf { bm2 = bm2 vf .□. 05, i85 = b }
134 -> vf { bm2 = bm2 vf .□. 06, i86 = b }
135 -> vf { bm2 = bm2 vf .□. 07, i87 = b }
136 -> vf { bm2 = bm2 vf .□. 08, i88 = b }
137 -> vf { bm2 = bm2 vf .□. 09, i89 = b }
138 -> vf { bm2 = bm2 vf .□. 10, i8A = b }
139 -> vf { bm2 = bm2 vf .□. 11, i8B = b }
140 -> vf { bm2 = bm2 vf .□. 12, i8C = b }
141 -> vf { bm2 = bm2 vf .□. 13, i8D = b }
142 -> vf { bm2 = bm2 vf .□. 14, i8E = b }
143 -> vf { bm2 = bm2 vf .□. 15, i8F = b }
144 -> vf { bm2 = bm2 vf .□. 16, i90 = b }
145 -> vf { bm2 = bm2 vf .□. 17, i91 = b }
146 -> vf { bm2 = bm2 vf .□. 18, i92 = b }
147 -> vf { bm2 = bm2 vf .□. 19, i93 = b }
148 -> vf { bm2 = bm2 vf .□. 20, i94 = b }
149 -> vf { bm2 = bm2 vf .□. 21, i95 = b }
150 -> vf { bm2 = bm2 vf .□. 22, i96 = b }
151 -> vf { bm2 = bm2 vf .□. 23, i97 = b }
152 -> vf { bm2 = bm2 vf .□. 24, i98 = b }
153 -> vf { bm2 = bm2 vf .□. 25, i99 = b }
154 -> vf { bm2 = bm2 vf .□. 26, i9A = b }
155 -> vf { bm2 = bm2 vf .□. 27, i9B = b }
156 -> vf { bm2 = bm2 vf .□. 28, i9C = b }
157 -> vf { bm2 = bm2 vf .□. 29, i9D = b }
158 -> vf { bm2 = bm2 vf .□. 30, i9E = b }
159 -> vf { bm2 = bm2 vf .□. 31, i9F = b }
160 -> vf { bm2 = bm2 vf .□. 32, iA0 = b }
161 -> vf { bm2 = bm2 vf .□. 33, iA1 = b }
162 -> vf { bm2 = bm2 vf .□. 34, iA2 = b }
163 -> vf { bm2 = bm2 vf .□. 35, iA3 = b }
164 -> vf { bm2 = bm2 vf .□. 36, iA4 = b }
165 -> vf { bm2 = bm2 vf .□. 37, iA5 = b }
166 -> vf { bm2 = bm2 vf .□. 38, iA6 = b }
167 -> vf { bm2 = bm2 vf .□. 39, iA7 = b }
168 -> vf { bm2 = bm2 vf .□. 40, iA8 = b }
169 -> vf { bm2 = bm2 vf .□. 41, iA9 = b }
170 -> vf { bm2 = bm2 vf .□. 42, iAA = b }
171 -> vf { bm2 = bm2 vf .□. 43, iAB = b }
172 -> vf { bm2 = bm2 vf .□. 44, iAC = b }
173 -> vf { bm2 = bm2 vf .□. 45, iAD = b }
174 -> vf { bm2 = bm2 vf .□. 46, iAE = b }
175 -> vf { bm2 = bm2 vf .□. 47, iAF = b }
176 -> vf { bm2 = bm2 vf .□. 48, iB0 = b }
177 -> vf { bm2 = bm2 vf .□. 49, iB1 = b }
178 -> vf { bm2 = bm2 vf .□. 50, iB2 = b }
179 -> vf { bm2 = bm2 vf .□. 51, iB3 = b }
180 -> vf { bm2 = bm2 vf .□. 52, iB4 = b }
181 -> vf { bm2 = bm2 vf .□. 53, iB5 = b }
182 -> vf { bm2 = bm2 vf .□. 54, iB6 = b }
183 -> vf { bm2 = bm2 vf .□. 55, iB7 = b }
184 -> vf { bm2 = bm2 vf .□. 56, iB8 = b }
185 -> vf { bm2 = bm2 vf .□. 57, iB9 = b }
186 -> vf { bm2 = bm2 vf .□. 58, iBA = b }
187 -> vf { bm2 = bm2 vf .□. 59, iBB = b }
188 -> vf { bm2 = bm2 vf .□. 60, iBC = b }
189 -> vf { bm2 = bm2 vf .□. 61, iBD = b }
190 -> vf { bm2 = bm2 vf .□. 62, iBE = b }
191 -> vf { bm2 = bm2 vf .□. 63, iBF = b }
192 -> vf { bm3 = bm3 vf .□. 00, iC0 = b }
193 -> vf { bm3 = bm3 vf .□. 01, iC1 = b }
194 -> vf { bm3 = bm3 vf .□. 02, iC2 = b }
195 -> vf { bm3 = bm3 vf .□. 03, iC3 = b }
196 -> vf { bm3 = bm3 vf .□. 04, iC4 = b }
197 -> vf { bm3 = bm3 vf .□. 05, iC5 = b }
198 -> vf { bm3 = bm3 vf .□. 06, iC6 = b }
199 -> vf { bm3 = bm3 vf .□. 07, iC7 = b }
200 -> vf { bm3 = bm3 vf .□. 08, iC8 = b }
201 -> vf { bm3 = bm3 vf .□. 09, iC9 = b }
202 -> vf { bm3 = bm3 vf .□. 10, iCA = b }
203 -> vf { bm3 = bm3 vf .□. 11, iCB = b }
204 -> vf { bm3 = bm3 vf .□. 12, iCC = b }
205 -> vf { bm3 = bm3 vf .□. 13, iCD = b }
206 -> vf { bm3 = bm3 vf .□. 14, iCE = b }
207 -> vf { bm3 = bm3 vf .□. 15, iCF = b }
208 -> vf { bm3 = bm3 vf .□. 16, iD0 = b }
209 -> vf { bm3 = bm3 vf .□. 17, iD1 = b }
210 -> vf { bm3 = bm3 vf .□. 18, iD2 = b }
211 -> vf { bm3 = bm3 vf .□. 19, iD3 = b }
212 -> vf { bm3 = bm3 vf .□. 20, iD4 = b }
213 -> vf { bm3 = bm3 vf .□. 21, iD5 = b }
214 -> vf { bm3 = bm3 vf .□. 22, iD6 = b }
215 -> vf { bm3 = bm3 vf .□. 23, iD7 = b }
216 -> vf { bm3 = bm3 vf .□. 24, iD8 = b }
217 -> vf { bm3 = bm3 vf .□. 25, iD9 = b }
218 -> vf { bm3 = bm3 vf .□. 26, iDA = b }
219 -> vf { bm3 = bm3 vf .□. 27, iDB = b }
220 -> vf { bm3 = bm3 vf .□. 28, iDC = b }
221 -> vf { bm3 = bm3 vf .□. 29, iDD = b }
222 -> vf { bm3 = bm3 vf .□. 30, iDE = b }
223 -> vf { bm3 = bm3 vf .□. 31, iDF = b }
224 -> vf { bm3 = bm3 vf .□. 32, iE0 = b }
225 -> vf { bm3 = bm3 vf .□. 33, iE1 = b }
226 -> vf { bm3 = bm3 vf .□. 34, iE2 = b }
227 -> vf { bm3 = bm3 vf .□. 35, iE3 = b }
228 -> vf { bm3 = bm3 vf .□. 36, iE4 = b }
229 -> vf { bm3 = bm3 vf .□. 37, iE5 = b }
230 -> vf { bm3 = bm3 vf .□. 38, iE6 = b }
231 -> vf { bm3 = bm3 vf .□. 39, iE7 = b }
232 -> vf { bm3 = bm3 vf .□. 40, iE8 = b }
233 -> vf { bm3 = bm3 vf .□. 41, iE9 = b }
234 -> vf { bm3 = bm3 vf .□. 42, iEA = b }
235 -> vf { bm3 = bm3 vf .□. 43, iEB = b }
236 -> vf { bm3 = bm3 vf .□. 44, iEC = b }
237 -> vf { bm3 = bm3 vf .□. 45, iED = b }
238 -> vf { bm3 = bm3 vf .□. 46, iEE = b }
239 -> vf { bm3 = bm3 vf .□. 47, iEF = b }
240 -> vf { bm3 = bm3 vf .□. 48, iF0 = b }
241 -> vf { bm3 = bm3 vf .□. 49, iF1 = b }
242 -> vf { bm3 = bm3 vf .□. 50, iF2 = b }
243 -> vf { bm3 = bm3 vf .□. 51, iF3 = b }
244 -> vf { bm3 = bm3 vf .□. 52, iF4 = b }
245 -> vf { bm3 = bm3 vf .□. 53, iF5 = b }
246 -> vf { bm3 = bm3 vf .□. 54, iF6 = b }
247 -> vf { bm3 = bm3 vf .□. 55, iF7 = b }
248 -> vf { bm3 = bm3 vf .□. 56, iF8 = b }
249 -> vf { bm3 = bm3 vf .□. 57, iF9 = b }
250 -> vf { bm3 = bm3 vf .□. 58, iFA = b }
251 -> vf { bm3 = bm3 vf .□. 59, iFB = b }
252 -> vf { bm3 = bm3 vf .□. 60, iFC = b }
253 -> vf { bm3 = bm3 vf .□. 61, iFD = b }
254 -> vf { bm3 = bm3 vf .□. 62, iFE = b }
255 -> vf { bm3 = bm3 vf .□. 63, iFF = b }
___ -> undefined -- Literal is out of Word8 range
where
b = undefined -- ⊥
--------------------------------------------------------------------------------
amount vf =
fromIntegral $
(.#.) (bm0 vf) +
(.#.) (bm1 vf) +
(.#.) (bm2 vf) +
(.#.) (bm3 vf)
bitmap vf =
map (bm0 vf .?.) [ 0 .. 63 ] ++
map (bm1 vf .?.) [ 0 .. 63 ] ++
map (bm2 vf .?.) [ 0 .. 63 ] ++
map (bm3 vf .?.) [ 0 .. 63 ]
pprint =
map (\x -> if x then '▣' else '□') . bitmap
tuples vf =
aux 0 $ bitmap vf
where
aux _ [ ] = []
aux i (False : xs) = i `seq` aux (i+1) xs
aux i (True : xs) = l `seq` (i, l) : aux (i+1) xs
where
l = lookup i vf
tolist =
map snd . tuples
--------------------------------------------------------------------------------
-- HELPERS
(.?.)
:: Bits a
=> a
-> Int
-> Bool
(.■.)
:: Bits a
=> a
-> Int
-> a
(.□.)
:: Bits a
=> a
-> Int
-> a
(.#.)
:: Bits a
=> a
-> Int
{-# INLINE (.?.) #-}
{-# INLINE (.■.) #-}
{-# INLINE (.□.) #-}
{-# INLINE (.#.) #-}
(.?.) = testBit
(.■.) = setBit
(.□.) = clearBit
(.#.) = popCount
exe/ArrayLog.hs
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
--------------------------------------------------------------------------------
--
-- ArrayLog, (c) 2020 SPISE MISU ApS
--
--------------------------------------------------------------------------------
{-# LANGUAGE Safe #-}
--------------------------------------------------------------------------------
module Main (main) where
--------------------------------------------------------------------------------
import Prelude hiding
( length
, lookup
)
import Data.Array.Log256
--------------------------------------------------------------------------------
main :: IO ()
main =
(putStrLn "# Before fmap") >>
(putStrLn . show . tuples $ a) >>
(putStrLn . pprint $ a) >>
(putStrLn "") >>
(putStrLn "# After fmap") >>
(putStrLn . show . tuples $ b) >>
(putStrLn . pprint $ b) >>
(putStrLn "") >>
(putStrLn "# Sparse (create)") >>
(putStrLn . show $ sparse a) >>
(putStrLn "") >>
(putStrLn "# Sparse (sliver)") >>
(putStrLn . show $ sparse s) >>
(putStrLn . pprint $ s) >>
(putStrLn "") >>
(putStrLn "# Sparse (expand)") >>
(putStrLn . show $ sparse e) >>
(putStrLn . pprint $ e) >>
(putStrLn "") >>
(putStrLn "# Sparse (defrag)") >>
(putStrLn . show $ sparse d) >>
(putStrLn . pprint $ d)
where
n = 300
m = 150
--
a = foldl (\ acc x -> update x x acc) (create n) $ take m [ 0 .. ]
b = fmap (*2) a
--
i = 050
o = 100
s = sliver i o b
--
e = expand 65536 s
--
d = defrag e
arraylog.cabal
cabal-version: 2.2
--------------------------------------------------------------------------------
--
-- ArrayLog, (c) 2020 SPISE MISU ApS
--
--------------------------------------------------------------------------------
build-type: Simple
name: arraylog
version: 0.11.0.0
synopsis: Data.Array.Log256 (SAFE, idiomatic and bottom).
description: Data.Array.Log256 (SAFE, idiomatic and bottom).
homepage: https://gitlab.com/spisemisu/arraylog
license: AGPL-3.0-only
license-file: LICENSE.md
author: Don Juan de la Cierva
maintainer: Don Juan de la Cierva
category: Safe and idiomatic Data Structures
--------------------------------------------------------------------------------
-- COMMON
--------------------------------------------------------------------------------
common both
default-language:
Haskell98
ghc-options:
--------------------------------------------------------------------------
-- GHC 8.6.5 Users Guide
-- 9. Using GHC > 9.2. Warnings and sanity-checking
-- * Base: https://downloads.haskell.org/~ghc/8.6.5/docs/html/users_guide/
-- * File: using-warnings.html
-- Warnings that are not enabled by -Wall:
--------------------------------------------------------------------------
-Wall
-Wincomplete-record-updates
-- -Wmonomorphism-restriction
-- -Wimplicit-prelude
-- -Wmissing-local-signatures
-Wmissing-exported-signatures
-- -Wmissing-export-lists
-- -Wmissing-import-lists
-Wmissing-home-modules
-Widentities
-Wredundant-constraints
-- Added since GHC 8.4
-Wpartial-fields
-- -Wmissed-specialisations
-- -Wall-missed-specialisations
--------------------------------------------------------------------------
-- Added to allow instance definition in other files, in order to keep the
-- Effect module SAFE so it can be imported by the Process
--------------------------------------------------------------------------
-Wno-orphans
-- Makes any warning into a fatal error.
-Werror
--------------------------------------------------------------------------
-- Deterministic builds (Uniques):
-- * https://gitlab.haskell.org/ghc/ghc/wikis/deterministic-builds#progress
-- * https://www.youtube.com/watch?v=FNzTk4P4fL4 (08 GHC Determinism ICFP)
--------------------------------------------------------------------------
-dinitial-unique=0
-dunique-increment=1
--------------------------------------------------------------------------
-- GHC 8.6.5 Users Guide
-- 19. Known bugs and infelicities >
-- 19.1. Haskell standards vs. Glasgow Haskell: language non-compliance >
-- 19.1.1.3. Expressions and patterns
-- * Base: https://downloads.haskell.org/~ghc/8.6.5/docs/html/users_guide/
-- * File: bugs.html
--------------------------------------------------------------------------
-fpedantic-bottoms
-- To use when GHC uses to many ticks:
-- -ddump-simpl-stats
-- -fsimpl-tick-factor=100
--------------------------------------------------------------------------
common libs
default-extensions:
Safe
ghc-options:
--------------------------------------------------------------------------
-- GHC 8.6.5 Users Guide
-- 12.40. Safe Haskell > ... > 12.40.1.1. Strict type-safety (good style)
-- * Enforce good style, similar to the function of -Wall.
-- Only Trustworthy packages can be trusted
-- * Base: https://downloads.haskell.org/~ghc/8.6.5/docs/html/users_guide/
-- * File: safe_haskell.html
--------------------------------------------------------------------------
-fpackage-trust
-trust=base
--------------------------------------------------------------------------
common bins
default-extensions:
Safe
ghc-options:
--------------------------------------------------------------------------
-- GHC 8.6.5 Users Guide
-- 12.40. Safe Haskell > ... > 12.40.1.1. Strict type-safety (good style)
-- * Enforce good style, similar to the function of -Wall.
-- Only Trustworthy packages can be trusted
-- * Base: https://downloads.haskell.org/~ghc/8.6.5/docs/html/users_guide/
-- * File: safe_haskell.html
--------------------------------------------------------------------------
-fpackage-trust
-trust=base
--------------------------------------------------------------------------
-- GHC 8.6.5 Users Guide
-- 9.3. Optimisation (code improvement)
-- * Base: https://downloads.haskell.org/~ghc/8.6.5/docs/html/users_guide/
-- * File: using-optimisation.html
--------------------------------------------------------------------------
-O2
-- -threaded
-- -rtsopts
-- -with-rtsopts=-N
--------------------------------------------------------------------------
-- The -N flag built-in can be modified on runtime based on the system
-- hosting the binary for optimal performance:
-- - https://hackage.haskell.org/package/base/docs/GHC-Conc.html
-- * getNumProcessors
-- - https://hackage.haskell.org/package/base/docs/Control-Concurrent.html
-- * setNumCapabilities
--------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- LIBRARY
--------------------------------------------------------------------------------
library
import:
both
, libs
hs-source-dirs:
src
exposed-modules:
Data.Array.Log256
, Data.Vector.Fixed256
build-depends:
-- Prelude
base >= 4 && < 5
--------------------------------------------------------------------------------
-- EXECUTABLES
--------------------------------------------------------------------------------
executable arraylog
import:
both
, bins
main-is:
ArrayLog.hs
hs-source-dirs:
exe
build-depends:
arraylog
-- Prelude
, base >= 4 && < 5
--------------------------------------------------------------------------------
-- REFERENCES
--------------------------------------------------------------------------------
-- HaskellStarter/haskell-starter.cabal:
-- https://github.com/joshcough/HaskellStarter/blob/master/haskell-starter.cabal
--------------------------------------------------------------------------------
stack.yaml
resolver: lts-14.27
packages:
- .
nix:
enable: true
packages: []
path: [
"nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/d858110.tar.gz"
]
## Reference
# Stack:
# - https://www.stackage.org/lts-14.27
# NixOS:
# - https://github.com/NixOS/nixpkgs-channels/branches/active
# - https://github.com/NixOS/nixpkgs-channels/tree/nixos-19.09
# - https://github.com/NixOS/nixpkgs-channels/tree/d858110
# - https://github.com/NixOS/nixpkgs-channels/archive/d858110.tar.gz
build.bash (real: 30m7.777s, user: 29m52.651s and sys: 0m15.487s)
#!/usr/bin/env bash
clear
bld="$(pwd)/.stack-work/install/x86_64-linux-nix/"
tgt="$(pwd)/bin"
echo "### Ensure folders exist:"
mkdir -v -p $bld;
mkdir -v -p $tgt;
echo
echo "### Clearing binaries:"
find $bld -mindepth 1 -name "*" -delete -print
find $tgt -mindepth 1 -name "*" -delete -print
echo
echo "### Stack building:"
#stack clean
#stack build --verbosity debug
#stack build --fast
stack build
echo
src="$(stack path --local-install-root)/bin"
echo "### Copying binaries to local $tgt:"
cp -v $src/* $tgt/
echo
echo "### Repoducible hashes:"
cd $tgt
for f in *; do
# skip all non-binaries
[[ $f == *.* ]] && continue
echo -e $(sha256sum $f | cut -d " " -f 1): $f
done;
echo
Code Output:

References:
- Stack Overflow:
- GitLab - Glasgow Haskell Compiler:
- GitLab - SPISE MISU ApS: