> {-# LANGUAGE FlexibleContexts #-}
> {-# LANGUAGE DataKinds #-}
> {-# LANGUAGE TypeOperators #-}
> {-# LANGUAGE FlexibleInstances #-}
> {-# LANGUAGE GADTs #-}
> {-# LANGUAGE UndecidableInstances #-}
> {-# LANGUAGE TypeFamilies #-}
> {-# LANGUAGE MultiParamTypeClasses #-}
> {-# LANGUAGE TypeApplications #-}
> {-# LANGUAGE ScopedTypeVariables #-}
> {-# LANGUAGE AllowAmbiguousTypes #-}
> {-# OPTIONS -Wno-missing-methods #-}
> module Figures where
> import Data.Type.Require
> import GHC.TypeLits
> import Data.Type.Bool
> import Data.Type.Equality
> import Data.Proxy
> data Color = RGB Nat Nat Nat
> type instance Equ (RGB r g b) (RGB r' g' b')
> = r == r' && g == g' && b == b'
> data Dim = R2 | R3
> type instance ShowTE R2 = Text "R2"
> type instance ShowTE R3 = Text "R3"
> data family Figure (d :: Dim) (c :: Color)
> data instance Figure R2 c
> = Circle Double Double Double
> data instance Figure R3 c
> = Sphere Double Double Double Double
> combine :: Figure d c -> Figure d c -> Figure d c
> combine :: Figure d c -> Figure d c -> Figure d c
combine Figure d c
f Figure d c
g = Figure d c
forall a. HasCallStack => a
undefined
combine (Circle 1 1 1) (Sphere 1 1 1 1) ->
• Couldn't match type ‘'R3’ with ‘'R2’
Expected type: Figure 'R2 c
Actual type: Figure 'R3 c
> data OpEqDim (d :: Dim) (d' :: Dim)
> data OpEqDim' (b :: Bool) (d :: Dim) (d' :: Dim)
> data OpEqCol (c :: Color) (c' :: Color)
> data OpEqCol' (b :: Bool) (c :: Color) (c' :: Color)
> data OpCombine d d' c c' where
> OpCombine :: Figure d c -> Figure d' c' -> OpCombine d d' c c'
> instance
> ( Require (OpEqDim d d') ctx
> , Require (OpEqCol c c') ctx
> )
> =>
> Require (OpCombine d d' c c') ctx where
> type ReqR (OpCombine d d' c c') =
> Figure d c
> req :: Proxy ctx -> OpCombine d d' c c' -> ReqR (OpCombine d d' c c')
req Proxy ctx
ctx (OpCombine Figure d c
f Figure d' c'
g) =
> ReqR (OpCombine d d' c c')
forall a. HasCallStack => a
undefined
> instance
> (Require (OpEqDim' (d == d') d d')) ctx
> =>
> Require (OpEqDim d d') ctx where
> type ReqR (OpEqDim d d') = ReqR (OpEqDim' (d == d') d d')
> instance Require (OpEqDim' 'True d d') ctx where {}
> instance
> Require (OpError
> (Text "Dimensional error:" :$$: Text "cannot combine figure of dimension "
> :<>: ShowTE d :<>: Text " and dimension " :<>: ShowTE d')) ctx
> => Require (OpEqDim' 'False d d') ctx
> instance
> (Require (OpEqCol' (Equ c c') c c')) ctx
> =>
> Require (OpEqCol c c') ctx where
> type ReqR (OpEqCol c c') = ReqR (OpEqCol' (Equ c c') c c')
> instance Require (OpEqCol' 'True c c') ctx where {}
an sloppy error:
> instance
> Require (OpError
> (Text "Error, combined images must be of the same color")) ctx
> => Require (OpEqCol' 'False c c') ctx
> combine' :: Figure d c -> Figure d' c' -> ReqR (OpCombine d d' c c')
combine' Figure d c
f Figure d' c'
f' = Proxy '[ 'Text "combining"]
-> OpCombine d d' c c' -> ReqR (OpCombine d d' c c')
forall op (ctx :: [ErrorMessage]).
Require op ctx =>
Proxy ctx -> op -> ReqR op
req (Proxy '[ 'Text "combining"]
forall k (t :: k). Proxy t
Proxy @( '[ Text "combining"] )) (Figure d c -> Figure d' c' -> OpCombine d d' c c'
forall (d :: Dim) (c :: Color) (d' :: Dim) (c' :: Color).
Figure d c -> Figure d' c' -> OpCombine d d' c c'
OpCombine Figure d c
f Figure d' c'
f')
combine' (Circle 1 1 1) (Sphere 1 1 1 1) ->
• Error: Dimensional error:
cannot combine figure of dimension R2 and dimension R3
trace: combining..
combine' (Circle 1 1 1 :: Figure R2 (RGB 1 1 1))
(Circle 1 1 1 :: Figure R2 (RGB 1 1 2)) ->
• Error: Error, combined images must be of the same color
trace: combining..
> f1 :: Figure 'R2 ('RGB 1 1 1)
f1 = (Double -> Double -> Double -> Figure 'R2 ('RGB 1 1 1)
forall (c :: Color). Double -> Double -> Double -> Figure 'R2 c
Circle Double
2 Double
2 Double
2 :: Figure R2 (RGB 1 1 1))
> f2 :: Figure 'R3 ('RGB 1 1 1)
f2 = (Double -> Double -> Double -> Double -> Figure 'R3 ('RGB 1 1 1)
forall (c :: Color).
Double -> Double -> Double -> Double -> Figure 'R3 c
Sphere Double
2 Double
2 Double
2 Double
2:: Figure R3 (RGB 1 1 1))
> f :: CFigure 'R2 ('RGB 1 1 1) ctx
f = (Proxy ctx -> Figure 'R2 ('RGB 1 1 1))
-> CFigure 'R2 ('RGB 1 1 1) ctx
forall (d :: Dim) (c :: Color) (ctx :: [ErrorMessage]).
(Proxy ctx -> Figure d c) -> CFigure d c ctx
CFigure ((Proxy ctx -> Figure 'R2 ('RGB 1 1 1))
-> CFigure 'R2 ('RGB 1 1 1) ctx)
-> (Proxy ctx -> Figure 'R2 ('RGB 1 1 1))
-> CFigure 'R2 ('RGB 1 1 1) ctx
forall a b. (a -> b) -> a -> b
$ \Proxy ctx
Proxy -> Figure 'R2 ('RGB 1 1 1)
f1
> f' :: CFigure 'R3 ('RGB 1 1 1) ctx
f' = (Proxy ctx -> Figure 'R3 ('RGB 1 1 1))
-> CFigure 'R3 ('RGB 1 1 1) ctx
forall (d :: Dim) (c :: Color) (ctx :: [ErrorMessage]).
(Proxy ctx -> Figure d c) -> CFigure d c ctx
CFigure ((Proxy ctx -> Figure 'R3 ('RGB 1 1 1))
-> CFigure 'R3 ('RGB 1 1 1) ctx)
-> (Proxy ctx -> Figure 'R3 ('RGB 1 1 1))
-> CFigure 'R3 ('RGB 1 1 1) ctx
forall a b. (a -> b) -> a -> b
$ \Proxy ctx
Proxy -> Figure 'R3 ('RGB 1 1 1)
f2
> f'' :: CFigure 'R3 ('RGB 1 1 1) ('Text "tracefig!!!!!" : ctx)
f'' = (Proxy ('Text "tracefig!!!!!" : ctx) -> Proxy ctx)
-> CFigure 'R3 ('RGB 1 1 1) ctx
-> CFigure 'R3 ('RGB 1 1 1) ('Text "tracefig!!!!!" : ctx)
forall (ctx' :: [ErrorMessage]) (ctx :: [ErrorMessage]) (d :: Dim)
(c :: Color).
(Proxy ctx' -> Proxy ctx) -> CFigure d c ctx -> CFigure d c ctx'
traceFig
> (\(Proxy ('Text "tracefig!!!!!" : ctx)
_ :: Proxy (Text "tracefig!!!!!" : ctx)) -> Proxy ctx
forall k (t :: k). Proxy t
Proxy :: Proxy ctx ) (CFigure 'R3 ('RGB 1 1 1) ctx
-> CFigure 'R3 ('RGB 1 1 1) ('Text "tracefig!!!!!" : ctx))
-> CFigure 'R3 ('RGB 1 1 1) ctx
-> CFigure 'R3 ('RGB 1 1 1) ('Text "tracefig!!!!!" : ctx)
forall a b. (a -> b) -> a -> b
$ CFigure 'R3 ('RGB 1 1 1) ctx
forall (ctx :: [ErrorMessage]). CFigure 'R3 ('RGB 1 1 1) ctx
f'
> tr :: CFigure d c ('Text "tracefig!!!!!" : ctx) -> CFigure d c ctx
tr = (Proxy ctx -> Proxy ('Text "tracefig!!!!!" : ctx))
-> CFigure d c ('Text "tracefig!!!!!" : ctx) -> CFigure d c ctx
forall (ctx' :: [ErrorMessage]) (ctx :: [ErrorMessage]) (d :: Dim)
(c :: Color).
(Proxy ctx' -> Proxy ctx) -> CFigure d c ctx -> CFigure d c ctx'
traceFig
> (\(Proxy ctx
_ :: Proxy (ctx)) -> Proxy ('Text "tracefig!!!!!" : ctx)
forall k (t :: k). Proxy t
Proxy :: Proxy (Text "tracefig!!!!!" : ctx) )
> data CFigure d c (ctx :: [ErrorMessage])
> = CFigure {CFigure d c ctx -> Proxy ctx -> Figure d c
mkCFig :: Proxy ctx -> Figure d c}
> combine''
> :: (Require (OpEqDim' (d == d') d d') (Text "lalo" :ctx),
> Require (OpEqCol' (Equ c c') c c') (Text "lalo" : ctx)) =>
> CFigure d c ctx -> CFigure d' c' ctx -> CFigure d c ctx
> combine'' :: CFigure d c ctx -> CFigure d' c' ctx -> CFigure d c ctx
combine'' (CFigure Proxy ctx -> Figure d c
f1) (CFigure Proxy ctx -> Figure d' c'
f2)
> = (Proxy ctx -> Figure d c) -> CFigure d c ctx
forall (d :: Dim) (c :: Color) (ctx :: [ErrorMessage]).
(Proxy ctx -> Figure d c) -> CFigure d c ctx
CFigure ((Proxy ctx -> Figure d c) -> CFigure d c ctx)
-> (Proxy ctx -> Figure d c) -> CFigure d c ctx
forall a b. (a -> b) -> a -> b
$ \(Proxy ctx
a :: Proxy ctx) ->
> Proxy ('Text "lalo" : ctx)
-> OpCombine d d' c c' -> ReqR (OpCombine d d' c c')
forall op (ctx :: [ErrorMessage]).
Require op ctx =>
Proxy ctx -> op -> ReqR op
req (Proxy ('Text "lalo" : ctx)
forall k (t :: k). Proxy t
Proxy :: Proxy (Text "lalo" : ctx))
> (Figure d c -> Figure d' c' -> OpCombine d d' c c'
forall (d :: Dim) (c :: Color) (d' :: Dim) (c' :: Color).
Figure d c -> Figure d' c' -> OpCombine d d' c c'
OpCombine (Proxy ctx -> Figure d c
f1 Proxy ctx
a) (Proxy ctx -> Figure d' c'
f2 Proxy ctx
a))
> traceFig :: (Proxy ctx' -> Proxy ctx) -> CFigure d c ctx -> CFigure d c ctx'
> traceFig :: (Proxy ctx' -> Proxy ctx) -> CFigure d c ctx -> CFigure d c ctx'
traceFig Proxy ctx' -> Proxy ctx
fctx (CFigure Proxy ctx -> Figure d c
f) = (Proxy ctx' -> Figure d c) -> CFigure d c ctx'
forall (d :: Dim) (c :: Color) (ctx :: [ErrorMessage]).
(Proxy ctx -> Figure d c) -> CFigure d c ctx
CFigure ((Proxy ctx' -> Figure d c) -> CFigure d c ctx')
-> (Proxy ctx' -> Figure d c) -> CFigure d c ctx'
forall a b. (a -> b) -> a -> b
$ Proxy ctx -> Figure d c
f (Proxy ctx -> Figure d c)
-> (Proxy ctx' -> Proxy ctx) -> Proxy ctx' -> Figure d c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy ctx' -> Proxy ctx
fctx
Error:
> g = combine'' (tr $ tr f) (tr $ tr f'')