diff options
author | Péter Diviánszky <divipp@gmail.com> | 2016-02-18 18:34:47 +0100 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2016-02-19 02:50:09 +0100 |
commit | 998ae8f884f4b1d4e092ebdf3a441b97b2cf05b7 (patch) | |
tree | 6ced17ee38fa78de69b05c8765288ecabe52fb6e /lc | |
parent | 27c8f3aeb2d13da0bec522ee8a8a98f534fa39e8 (diff) |
tuples are heterogeneous lists
Diffstat (limited to 'lc')
-rw-r--r-- | lc/Builtins.lc | 122 | ||||
-rw-r--r-- | lc/Internals.lc | 63 | ||||
-rw-r--r-- | lc/Prelude.lc | 29 |
3 files changed, 105 insertions, 109 deletions
diff --git a/lc/Builtins.lc b/lc/Builtins.lc index 7ad75672..a0b9e5e0 100644 --- a/lc/Builtins.lc +++ b/lc/Builtins.lc | |||
@@ -1,4 +1,5 @@ | |||
1 | {-# LANGUAGE NoImplicitPrelude #-} | 1 | {-# LANGUAGE NoImplicitPrelude #-} |
2 | |||
2 | module Builtins | 3 | module Builtins |
3 | ( module Internals | 4 | ( module Internals |
4 | , module Builtins | 5 | , module Builtins |
@@ -26,10 +27,6 @@ type family VecScalar (n :: Nat) a where | |||
26 | VecScalar 1 a = a | 27 | VecScalar 1 a = a |
27 | VecScalar ('Succ ('Succ n)) a = Vec ('Succ ('Succ n)) a | 28 | VecScalar ('Succ ('Succ n)) a = Vec ('Succ ('Succ n)) a |
28 | 29 | ||
29 | -- may be a data family? | ||
30 | type family TFVec (n :: Nat) a where | ||
31 | TFVec n a = Vec n a -- TODO: check range: n = 2,3,4; a is Float, Int, Word, Bool | ||
32 | |||
33 | -- todo: use less constructors with more parameters | 30 | -- todo: use less constructors with more parameters |
34 | data Mat :: Nat -> Nat -> Type -> Type where | 31 | data Mat :: Nat -> Nat -> Type -> Type where |
35 | M22F :: Vec 2 Float -> Vec 2 Float -> Mat 2 2 Float | 32 | M22F :: Vec 2 Float -> Vec 2 Float -> Mat 2 2 Float |
@@ -252,10 +249,12 @@ data RasterContext a :: PrimitiveType -> Type where | |||
252 | PointCtx :: PointSize a -> Float -> PointSpriteCoordOrigin -> RasterContext a Point | 249 | PointCtx :: PointSize a -> Float -> PointSpriteCoordOrigin -> RasterContext a Point |
253 | LineCtx :: Float -> ProvokingVertex -> RasterContext a Line | 250 | LineCtx :: Float -> ProvokingVertex -> RasterContext a Line |
254 | 251 | ||
255 | type family FTRepr' a where | 252 | map _ [] = [] |
256 | -- TODO | 253 | map f (x:xs) = f x : map f xs |
257 | FTRepr' [a] = a | 254 | |
258 | FTRepr' ([a], [b]) = (a, b) | 255 | type family ListElem a where ListElem [a] = a |
256 | |||
257 | type family HListElem a :: [Type] where HListElem (HList l) = l | ||
259 | 258 | ||
260 | data Blending :: Type -> Type where | 259 | data Blending :: Type -> Type where |
261 | NoBlending :: Blending t | 260 | NoBlending :: Blending t |
@@ -264,28 +263,15 @@ data Blending :: Type -> Type where | |||
264 | -> ((BlendingFactor, BlendingFactor), (BlendingFactor, BlendingFactor)) | 263 | -> ((BlendingFactor, BlendingFactor), (BlendingFactor, BlendingFactor)) |
265 | -> Vec 4 Float -> Blending Float | 264 | -> Vec 4 Float -> Blending Float |
266 | 265 | ||
267 | {- TODO: more precise kinds | ||
268 | FragmentOperation :: Semantic -> * | ||
269 | FragmentOut :: Semantic -> * | ||
270 | -} | ||
271 | |||
272 | data StencilTests | 266 | data StencilTests |
273 | data StencilOps | 267 | data StencilOps |
274 | data Int32 | 268 | data Int32 |
275 | 269 | ||
276 | data FragmentOperation :: ImageSemantics -> Type where | 270 | data FragmentOperation :: ImageSemantics -> Type where |
277 | ColorOp :: (mask ~ VecScalar d Bool, color ~ VecScalar d c, Num c) => Blending c -> mask | 271 | ColorOp :: Num c => Blending c -> VecScalar d Bool -> FragmentOperation (Color (VecScalar d c)) |
278 | -> FragmentOperation (Color color) | ||
279 | DepthOp :: ComparisonFunction -> Bool -> FragmentOperation (Depth Float) | 272 | DepthOp :: ComparisonFunction -> Bool -> FragmentOperation (Depth Float) |
280 | StencilOp :: StencilTests -> StencilOps -> StencilOps -> FragmentOperation (Stencil Int32) | 273 | StencilOp :: StencilTests -> StencilOps -> StencilOps -> FragmentOperation (Stencil Int32) |
281 | 274 | ||
282 | type family FragOps (a :: [ImageSemantics]) where | ||
283 | FragOps '[t] = (FragmentOperation t) | ||
284 | FragOps '[t1, t2] = (FragmentOperation t1, FragmentOperation t2) | ||
285 | FragOps '[t1, t2, t3] = (FragmentOperation t1, FragmentOperation t2, FragmentOperation t3) | ||
286 | FragOps '[t1, t2, t3, t4] = (FragmentOperation t1, FragmentOperation t2, FragmentOperation t3, FragmentOperation t4) | ||
287 | FragOps '[t1, t2, t3, t4, t5] = (FragmentOperation t1, FragmentOperation t2, FragmentOperation t3, FragmentOperation t4, FragmentOperation t5) | ||
288 | |||
289 | [] ++ ys = ys | 275 | [] ++ ys = ys |
290 | x:xs ++ ys = x : xs ++ ys | 276 | x:xs ++ ys = x : xs ++ ys |
291 | 277 | ||
@@ -294,9 +280,6 @@ foldr f e (x: xs) = f x (foldr f e xs) | |||
294 | 280 | ||
295 | concat = foldr (++) [] | 281 | concat = foldr (++) [] |
296 | 282 | ||
297 | map _ [] = [] | ||
298 | map f (x:xs) = f x : map f xs | ||
299 | |||
300 | concatMap :: (a -> [b]) -> [a] -> [b] | 283 | concatMap :: (a -> [b]) -> [a] -> [b] |
301 | concatMap f x = concat (map f x) | 284 | concatMap f x = concat (map f x) |
302 | 285 | ||
@@ -315,7 +298,7 @@ mapPrimitive f (PrimTriangle a b c) = PrimTriangle (f a) (f b) (f c) | |||
315 | -} | 298 | -} |
316 | 299 | ||
317 | fetch_ :: forall a t . (AttributeTuple t) => String -> t -> PrimitiveStream a t | 300 | fetch_ :: forall a t . (AttributeTuple t) => String -> t -> PrimitiveStream a t |
318 | fetchArrays_ :: forall a t t' . (AttributeTuple t, t ~ FTRepr' t') => t' -> PrimitiveStream a t | 301 | fetchArrays_ :: forall a t t' . (AttributeTuple t, t ~ HList (map ListElem (HListElem t'))) => t' -> PrimitiveStream a t |
319 | 302 | ||
320 | mapPrimitives :: (a -> b) -> PrimitiveStream p a -> PrimitiveStream p b | 303 | mapPrimitives :: (a -> b) -> PrimitiveStream p a -> PrimitiveStream p b |
321 | mapPrimitives f = map (mapPrimitive f) | 304 | mapPrimitives f = map (mapPrimitive f) |
@@ -323,23 +306,6 @@ mapPrimitives f = map (mapPrimitive f) | |||
323 | fetch s a t = fetch_ @a s t | 306 | fetch s a t = fetch_ @a s t |
324 | fetchArrays a t = fetchArrays_ @a t | 307 | fetchArrays a t = fetchArrays_ @a t |
325 | 308 | ||
326 | remSemantics :: ImageSemantics -> Type | ||
327 | remSemantics (Color a) = a | ||
328 | remSemantics (Depth a) = a | ||
329 | remSemantics (Stencil a) = a | ||
330 | |||
331 | remSemantics_ :: [ImageSemantics] -> Type | ||
332 | remSemantics_ [] = '() | ||
333 | remSemantics_ [a] = remSemantics a | ||
334 | remSemantics_ [a, b] = '(remSemantics a, remSemantics b) | ||
335 | remSemantics_ [a, b, c] = '(remSemantics a, remSemantics b, remSemantics c) | ||
336 | remSemantics_ [a, b, c, d] = '(remSemantics a, remSemantics b, remSemantics c, remSemantics d) | ||
337 | remSemantics_ [a, b, c, d, e] = '(remSemantics a, remSemantics b, remSemantics c, remSemantics d, remSemantics e) | ||
338 | |||
339 | remSemantics' :: [ImageSemantics] -> Type | ||
340 | remSemantics' (Depth _: x) = remSemantics_ x | ||
341 | remSemantics' x = remSemantics_ x | ||
342 | |||
343 | ------------------- | 309 | ------------------- |
344 | 310 | ||
345 | data Maybe a | 311 | data Maybe a |
@@ -379,21 +345,13 @@ data Interpolated t where | |||
379 | :: (Floating t) => Interpolated t | 345 | :: (Floating t) => Interpolated t |
380 | Flat :: Interpolated t | 346 | Flat :: Interpolated t |
381 | 347 | ||
382 | type family InterpolatedType a where | ||
383 | InterpolatedType () = () | ||
384 | InterpolatedType (Interpolated a) = a | ||
385 | InterpolatedType (Interpolated a, Interpolated b) = (a, b) | ||
386 | InterpolatedType (Interpolated a, Interpolated b, Interpolated c) = (a, b, c) | ||
387 | InterpolatedType (Interpolated a, Interpolated b, Interpolated c, Interpolated d) = (a, b, c, d) | ||
388 | InterpolatedType (Interpolated a, Interpolated b, Interpolated c, Interpolated d, Interpolated e) = (a, b, c, d, e) | ||
389 | |||
390 | rasterizePrimitive | 348 | rasterizePrimitive |
391 | :: ( b ~ InterpolatedType interpolation | 349 | :: ( map Interpolated b ~ interpolation |
392 | , a ~ JoinTupleType (Vec 4 Float) b ) | 350 | , a ~ 'Cons (Vec 4 Float) b ) |
393 | => interpolation -- tuple of Smooth & Flat | 351 | => HList interpolation -- tuple of Smooth & Flat |
394 | -> RasterContext a x | 352 | -> RasterContext (HList a) x |
395 | -> Primitive a x | 353 | -> Primitive (HList a) x |
396 | -> FragmentStream 1 b | 354 | -> FragmentStream 1 (HList b) |
397 | 355 | ||
398 | rasterizePrimitives ctx is s = concat (map (rasterizePrimitive is ctx) s) | 356 | rasterizePrimitives ctx is s = concat (map (rasterizePrimitive is ctx) s) |
399 | 357 | ||
@@ -404,14 +362,19 @@ ColorImage :: forall a d t color . (Num t, color ~ VecScalar d t) | |||
404 | DepthImage :: forall a . Float -> Image a (Depth Float) | 362 | DepthImage :: forall a . Float -> Image a (Depth Float) |
405 | StencilImage :: forall a . Int -> Image a (Stencil Int) | 363 | StencilImage :: forall a . Int -> Image a (Stencil Int) |
406 | 364 | ||
407 | type family SameLayerCounts a where | 365 | type family ImageLC a :: Nat where ImageLC (Image n t) = n |
408 | SameLayerCounts (Image n1 t1) = Unit | 366 | |
409 | SameLayerCounts (Image n1 t1, Image n2 t2) = EqCT Nat n1 n2 | 367 | allSame :: [a] -> Type |
410 | SameLayerCounts (Image n1 t1, Image n2 t2, Image n3 t3) = T2 (EqCT Nat n1 n2) (EqCT Nat n1 n3) | 368 | allSame [] = 'Unit |
369 | allSame [x] = 'Unit | ||
370 | allSame (x: y: xs) = 'T2 (x ~ y) (allSame (y:xs)) | ||
371 | |||
372 | sameLayerCounts a = allSame (map 'ImageLC a) | ||
373 | |||
411 | {- | 374 | {- |
412 | class DefaultFragOp a where defaultFragOp :: FragmentOperation a | 375 | defaultFragOp :: forall (a :: ImageSemantics) -> FragmentOperation a |
413 | instance DefaultFragOp (Color (VecS Float 4)) where defaultFragOp = ColorOp NoBlending (V4 True True True True) | 376 | defaultFragOp (Color '(VecS Float 4)) = ColorOp NoBlending (V4 True True True True) |
414 | instance DefaultFragOp (Depth Float) where defaultFragOp = DepthOp Less True | 377 | defaultFragOp (Depth 'Float) = DepthOp Less True |
415 | 378 | ||
416 | class DefaultFragOps a where defaultFragOps :: a | 379 | class DefaultFragOps a where defaultFragOps :: a |
417 | instance (DefaultFragOp a, DefaultFragOp b) => DefaultFragOps (FragmentOperation a, FragmentOperation b) where | 380 | instance (DefaultFragOp a, DefaultFragOp b) => DefaultFragOps (FragmentOperation a, FragmentOperation b) where |
@@ -420,20 +383,35 @@ instance (DefaultFragOp a, DefaultFragOp b) => DefaultFragOps (FragmentOperation | |||
420 | -} | 383 | -} |
421 | data FrameBuffer (n :: Nat) (t :: [ImageSemantics]) | 384 | data FrameBuffer (n :: Nat) (t :: [ImageSemantics]) |
422 | 385 | ||
423 | Accumulate :: FragOps b -> FragmentStream n (remSemantics' b) -> FrameBuffer n b -> FrameBuffer n b | 386 | remSemantics :: ImageSemantics -> Type |
387 | remSemantics (Color a) = a | ||
388 | remSemantics (Depth a) = a | ||
389 | remSemantics (Stencil a) = a | ||
390 | |||
391 | remSemantics' :: [ImageSemantics] -> [Type] | ||
392 | remSemantics' (Depth _: x) = map remSemantics x | ||
393 | remSemantics' x = map remSemantics x | ||
424 | 394 | ||
425 | type family TFFrameBuffer a where | 395 | type family FragmentOperationSem a :: ImageSemantics |
426 | TFFrameBuffer (Image n1 t1) = FrameBuffer n1 '[t1] | 396 | type instance FragmentOperationSem (FragmentOperation x) = x |
427 | TFFrameBuffer (Image n1 t1, Image n2 t2) = FrameBuffer n1 '[t1, t2] | 397 | |
428 | TFFrameBuffer (Image n1 t1, Image n2 t2, Image n3 t3) = FrameBuffer n1 '[t1, t2, t3] | 398 | Accumulate :: forall (n :: Nat) (c :: [Type]) . (b ~ map FragmentOperationSem c) => HList c -> FragmentStream n (HList (remSemantics' b)) -> FrameBuffer n b -> FrameBuffer n b |
399 | |||
400 | type family ImageSem a :: ImageSemantics | ||
401 | type instance ImageSem (Image n t) = t | ||
402 | |||
403 | tfFrameBuffer t = map 'ImageSem t | ||
429 | 404 | ||
430 | class ValidFrameBuffer (a :: [ImageSemantics]) | 405 | class ValidFrameBuffer (a :: [ImageSemantics]) |
431 | instance ValidFrameBuffer a -- TODO | 406 | instance ValidFrameBuffer a -- TODO |
432 | 407 | ||
433 | FrameBuffer :: (ValidFrameBuffer b, SameLayerCounts a, FrameBuffer n b ~ TFFrameBuffer a) => a -> FrameBuffer n b | 408 | head (x: _) = x |
409 | |||
410 | FrameBuffer :: forall (a :: [Type]) . (sameLayerCounts a) => HList a -> FrameBuffer (ImageLC (head a)) (tfFrameBuffer a) | ||
434 | 411 | ||
435 | accumulate ctx fshader fstr fb = Accumulate ctx (mapFragments fshader fstr) fb | 412 | accumulate ctx fshader fstr fb = Accumulate ctx (mapFragments fshader fstr) fb |
436 | 413 | ||
414 | -- todo: remove | ||
437 | accumulationContext x = x | 415 | accumulationContext x = x |
438 | 416 | ||
439 | -- texture support | 417 | -- texture support |
@@ -480,9 +458,9 @@ PrimClampS :: (Num t, a ~ VecScalar d t) => a -> t -> t -> a | |||
480 | PrimMix :: (a ~ VecScalar d Float) => a -> a -> a -> a | 458 | PrimMix :: (a ~ VecScalar d Float) => a -> a -> a -> a |
481 | PrimMixS :: (a ~ VecScalar d Float) => a -> a -> Float -> a | 459 | PrimMixS :: (a ~ VecScalar d Float) => a -> a -> Float -> a |
482 | PrimMixB :: (a ~ VecScalar d Float, b ~ VecScalar d Bool) => a -> a -> b -> a | 460 | PrimMixB :: (a ~ VecScalar d Float, b ~ VecScalar d Bool) => a -> a -> b -> a |
483 | PrimStep :: (a ~ TFVec d Float) => a -> a -> a | 461 | PrimStep :: (a ~ Vec d Float) => a -> a -> a |
484 | PrimStepS :: (a ~ VecScalar d Float) => Float -> a -> a | 462 | PrimStepS :: (a ~ VecScalar d Float) => Float -> a -> a |
485 | PrimSmoothStep :: (a ~ TFVec d Float) => a -> a -> a -> a | 463 | PrimSmoothStep :: (a ~ Vec d Float) => a -> a -> a -> a |
486 | PrimSmoothStepS :: (a ~ VecScalar d Float) => Float -> Float -> a -> a | 464 | PrimSmoothStepS :: (a ~ VecScalar d Float) => Float -> Float -> a -> a |
487 | 465 | ||
488 | -- Integer/Floatonversion Functions | 466 | -- Integer/Floatonversion Functions |
diff --git a/lc/Internals.lc b/lc/Internals.lc index 8a8bfe6f..9005cb0f 100644 --- a/lc/Internals.lc +++ b/lc/Internals.lc | |||
@@ -1,11 +1,13 @@ | |||
1 | {-# LANGUAGE NoImplicitPrelude #-} | 1 | {-# LANGUAGE NoImplicitPrelude #-} |
2 | {-# LANGUAGE TraceTypeCheck #-} | ||
3 | -- declarations of builtin functions and data types used by the compiler | 2 | -- declarations of builtin functions and data types used by the compiler |
4 | module Internals where | 3 | module Internals where |
5 | 4 | ||
6 | -- used for type annotations | 5 | -- used for type annotations |
7 | typeAnn x = x | 6 | typeAnn x = x |
8 | 7 | ||
8 | -- used for recognising double parenthesis | ||
9 | parens x = x | ||
10 | |||
9 | undefined :: forall (a :: Type) . a | 11 | undefined :: forall (a :: Type) . a |
10 | 12 | ||
11 | primFix :: forall (a :: Type) . (a -> a) -> a | 13 | primFix :: forall (a :: Type) . (a -> a) -> a |
@@ -22,40 +24,17 @@ type family EqCT (t :: Type) (a :: t) (b :: t) | |||
22 | coe :: forall (a :: Type) (b :: Type) -> EqCT Type a b -> a -> b | 24 | coe :: forall (a :: Type) (b :: Type) -> EqCT Type a b -> a -> b |
23 | coe a b TT x = unsafeCoerce @a @b x | 25 | coe a b TT x = unsafeCoerce @a @b x |
24 | -} | 26 | -} |
25 | -- TODO: generate? | ||
26 | data Tuple0 = Tuple0 | ||
27 | data Tuple1 a = Tuple1 a | ||
28 | data Tuple2 a b = Tuple2 a b | ||
29 | data Tuple3 a b c = Tuple3 a b c | ||
30 | data Tuple4 a b c d = Tuple4 a b c d | ||
31 | data Tuple5 a b c d e = Tuple5 a b c d e | ||
32 | 27 | ||
33 | -- ... TODO | 28 | -- ... TODO |
34 | 29 | ||
35 | -- builtin used for overlapping instances | 30 | -- builtin used for overlapping instances |
36 | parEval :: forall a -> a -> a -> a | 31 | parEval :: forall a -> a -> a -> a |
37 | 32 | ||
38 | type family JoinTupleType t1 t2 where | ||
39 | -- TODO | ||
40 | JoinTupleType a () = a | ||
41 | JoinTupleType a (b, c) = (a, b, c) | ||
42 | JoinTupleType a (b, c, d) = (a, b, c, d) | ||
43 | JoinTupleType a (b, c, d, e) = (a, b, c, d, e) | ||
44 | JoinTupleType a b = (a, b) | ||
45 | |||
46 | -- conjuction of constraints | 33 | -- conjuction of constraints |
47 | type family T2 a b | 34 | type family T2 a b |
48 | 35 | ||
49 | match'Type :: forall (m :: Type -> Type) -> m Type -> forall (t :: Type) -> m t -> m t | 36 | match'Type :: forall (m :: Type -> Type) -> m Type -> forall (t :: Type) -> m t -> m t |
50 | 37 | ||
51 | testmt :: forall (t :: Type) -> t -> t | ||
52 | testmt 'Type = \'Tuple0 -> 'Tuple0 | ||
53 | --testmt t x = (match'Type (\q -> (q -> q)) (\x -> match'Tuple0 (\q -> & 'Type) 'Tuple0 x undefined) t undefined) x | ||
54 | --testmt t x = (match'Type (\q -> (q -> q)) (\x -> match'Tuple0 (\q -> 'Type) 'Tuple0 x undefined) t undefined) x | ||
55 | |||
56 | --type instance EqCT Type = \'Type 'Type -> 'Unit | ||
57 | --type instance EqCT Type = \'(a, b) '(JoinTupleType a' b') -> '(T2 (EqCT Type a a') (EqCT Type b b')) | ||
58 | |||
59 | type EqCTt = EqCT _ | 38 | type EqCTt = EqCT _ |
60 | 39 | ||
61 | -- builtin conjuction of constraint witnesses | 40 | -- builtin conjuction of constraint witnesses |
@@ -144,4 +123,40 @@ data List a = Nil | Cons a (List a) | |||
144 | 123 | ||
145 | infixr 5 : | 124 | infixr 5 : |
146 | 125 | ||
126 | data HList :: [Type] -> Type where | ||
127 | HNil :: HList '[] | ||
128 | HCons :: x -> HList xs -> HList '(x: xs) | ||
129 | |||
130 | hlistConsCase | ||
131 | :: forall (e :: Type) (f :: List Type) | ||
132 | . forall (c :: Unit -> Type) | ||
133 | -> (e -> HList f -> c 'TT) | ||
134 | -> HList (Cons e f) | ||
135 | -> c 'TT | ||
136 | {- | ||
137 | -- TODO: unsafeCoerce is not really needed here | ||
138 | hlistConsCase @e @f c fv x = 'HListCase | ||
139 | (\_ _ -> c TT) | ||
140 | undefined | ||
141 | (\ @t @lt y ys -> fv (unsafeCoerce @t @e y) (unsafeCoerce @(HList lt) @(HList f) ys)) | ||
142 | x | ||
143 | -} | ||
144 | hlistNilCase :: forall (c :: Unit -> Type) -> c 'TT -> HList Nil -> c 'TT | ||
145 | {- | ||
146 | hlistNilCase c x v = 'HListCase | ||
147 | (\_ _ -> c TT) | ||
148 | x | ||
149 | (\_ _ -> undefined :: c TT) | ||
150 | v | ||
151 | -} | ||
152 | |||
153 | --testmt :: forall (t :: Type) -> t -> t | ||
154 | --testmt 'Type = \'Tuple0 -> 'Tuple0 | ||
155 | --testmt t x = (match'Type (\q -> (q -> q)) (\x -> match'Tuple0 (\q -> & 'Type) 'Tuple0 x undefined) t undefined) x | ||
156 | --testmt t x = (match'Type (\q -> (q -> q)) (\x -> match'Tuple0 (\q -> 'Type) 'Tuple0 x undefined) t undefined) x | ||
157 | |||
158 | --type instance EqCT Type = \'Type 'Type -> 'Unit | ||
159 | --type instance EqCT Type = \'(a, b) '(JoinTupleType a' b') -> '(T2 (EqCT Type a a') (EqCT Type b b')) | ||
160 | |||
161 | joinTupleType = HCons | ||
147 | 162 | ||
diff --git a/lc/Prelude.lc b/lc/Prelude.lc index c3b819d9..25e2331a 100644 --- a/lc/Prelude.lc +++ b/lc/Prelude.lc | |||
@@ -43,8 +43,8 @@ filter pred (x:xs) = case pred x of | |||
43 | True -> (x : filter pred xs) | 43 | True -> (x : filter pred xs) |
44 | False -> (filter pred xs) | 44 | False -> (filter pred xs) |
45 | 45 | ||
46 | head :: [a] -> a | 46 | --head :: [a] -> a |
47 | head (a: _) = a | 47 | --head (a: _) = a |
48 | 48 | ||
49 | tail :: [a] -> [a] | 49 | tail :: [a] -> [a] |
50 | tail (_: xs) = xs | 50 | tail (_: xs) = xs |
@@ -76,13 +76,6 @@ iterate f x = x : iterate f (f x) | |||
76 | fst (a, b) = a | 76 | fst (a, b) = a |
77 | snd (a, b) = b | 77 | snd (a, b) = b |
78 | 78 | ||
79 | tuptype :: [Type] -> Type | ||
80 | tuptype [] = '() | ||
81 | tuptype (x:xs) = '(x, tuptype xs) | ||
82 | |||
83 | data RecordC (xs :: [(String, Type)]) | ||
84 | = RecordCons (tuptype (map snd xs)) | ||
85 | |||
86 | False ||| x = x | 79 | False ||| x = x |
87 | True ||| x = True | 80 | True ||| x = True |
88 | 81 | ||
@@ -126,13 +119,23 @@ record :: [(String, Type)] -> Type | |||
126 | --record xs = RecordCons ({- TODO: sortBy fst-} xs) | 119 | --record xs = RecordCons ({- TODO: sortBy fst-} xs) |
127 | -} | 120 | -} |
128 | 121 | ||
122 | data RecItem = RecItem String Type | ||
123 | |||
124 | recItemType (RecItem _ t) = t | ||
125 | |||
126 | data RecordC (xs :: [RecItem]) | ||
127 | = RecordCons (HList (map recItemType xs)) | ||
128 | |||
129 | isKeyC _ _ [] = 'Empty "" | 129 | isKeyC _ _ [] = 'Empty "" |
130 | isKeyC s t ((s', t'): ss) = if s == s' then t ~ t' else isKeyC s t ss | 130 | isKeyC s t (RecItem s' t': ss) = if s == s' then t ~ t' else isKeyC s t ss |
131 | |||
132 | fstTup (HCons a _) = a | ||
133 | sndTup (HCons _ a) = a | ||
131 | 134 | ||
132 | -- todo: don't use unsafeCoerce | 135 | -- todo: don't use unsafeCoerce |
133 | project :: forall a (xs :: [(String, Type)]) . forall (s :: String) -> 'isKeyC s a xs => RecordC xs -> a | 136 | project :: forall a (xs :: [RecItem]) . forall (s :: String) -> 'isKeyC s a xs => RecordC xs -> a |
134 | project @a @((s', a'): xs) s @_ (RecordCons ts) | s == s' = fst (unsafeCoerce @_ @(a, tuptype (map snd xs)) ts) | 137 | project @a @(RecItem s' a': xs) s @_ (RecordCons ts) | s == s' = fstTup (unsafeCoerce @_ @(HList '(a : map recItemType xs)) ts) |
135 | project @a @((s', a'): xs) s @_ (RecordCons ts) = project @a @xs s @(undefined @(isKeyC s a xs)) (RecordCons (snd (unsafeCoerce @_ @(a, tuptype (map snd xs)) ts))) | 138 | project @a @(RecItem s' a': xs) s @_ (RecordCons ts) = project @a @xs s @(undefined @(isKeyC s a xs)) (RecordCons (sndTup (unsafeCoerce @_ @(HList '(a : map recItemType xs)) ts))) |
136 | 139 | ||
137 | --------------------------------------- HTML colors | 140 | --------------------------------------- HTML colors |
138 | 141 | ||