Skip to content

Commit 0be02a0

Browse files
committed
2 parents 4d75ba0 + 160f5e6 commit 0be02a0

File tree

19 files changed

+1851
-658
lines changed

19 files changed

+1851
-658
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
2+
{-# LANGUAGE TypeOperators #-}
3+
{-# LANGUAGE MultiParamTypeClasses #-}
4+
{-# LANGUAGE FlexibleInstances #-}
5+
6+
module Combination.Calculus where
7+
8+
import Calculus.FunExpr
9+
import Calculus.DifferentialCalc
10+
import Calculus.IntegralCalc
11+
12+
import Combination.Quantity
13+
import Dimensions.TypeLevel
14+
15+
import Combination.Vector
16+
17+
import Prelude hiding (length)
18+
19+
-- FunExpr är redan Num-instans, så borde inte behöva göra detta,
20+
-- men pga okända anledningar funkar det ej
21+
22+
instance Addable FunExpr FunExpr FunExpr where
23+
doAdd = (+)
24+
25+
instance Subable FunExpr FunExpr FunExpr where
26+
doSub = (-)
27+
28+
instance Multiplicable FunExpr FunExpr FunExpr where
29+
doMul = (*)
30+
31+
instance Divisionable FunExpr FunExpr FunExpr where
32+
doDiv = (:/)
33+
34+
-- Det intressanta är att den är Calculable! Num är faktiskt inte det
35+
-- så här blir det spännande.
36+
37+
instance Calculable FunExpr where
38+
doDif = simplify . derive
39+
doInteg = simplify . integrate
40+
41+
42+
----------------------------------------
43+
-- Exempel
44+
----------------------------------------
45+
46+
-- Ett flygplan med viss position är nedanstående
47+
48+
g1 = V3 Id (Const 3 :* Exp) Sin ## length
49+
50+
-- Dess hastighet är
51+
52+
g2 :: Quantity (Length `Div` Time) (Vector3 FunExpr)
53+
g2 = diff g1
54+
55+
-- Dess acceleration är
56+
57+
g3 :: Quantity ((Length `Div` Time) `Div` Time) (Vector3 FunExpr)
58+
g3 = diff g2
59+
60+
-- Det väger 120 kg
61+
62+
g4 :: Quantity Mass FunExpr
63+
g4 = Const 120 ## mass
64+
65+
-- Så nettokraften är
66+
67+
g5 :: Quantity (Mass `Mul` ((Length `Div` Time) `Div` Time)) (Vector3 FunExpr)
68+
g5 = g4 *# g3
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+
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
2+
{-# LANGUAGE UndecidableInstances #-}
3+
{-# LANGUAGE FlexibleInstances #-}
4+
{-# LANGUAGE GADTs #-}
5+
{-# LANGUAGE DataKinds #-}
6+
{-# LANGUAGE TypeOperators #-}
7+
{-# LANGUAGE KindSignatures #-}
8+
9+
{-# LANGUAGE MultiParamTypeClasses #-}
10+
11+
module Combination.Quantity where
12+
13+
import qualified Dimensions.ValueLevel as V
14+
import Dimensions.TypeLevel as T
15+
import Prelude as P hiding (length)
16+
17+
----------------------------------------
18+
-- Än så länge inget nytt
19+
----------------------------------------
20+
21+
data Quantity (d :: T.Dim) (v :: *) where
22+
ValQuantity :: V.Dim -> v -> Quantity d v
23+
24+
showQuantity :: (Show v) => Quantity d v -> String
25+
showQuantity (ValQuantity d v) = show v ++ " " ++ show d
26+
27+
instance (Show v) => Show (Quantity d v) where
28+
show = showQuantity
29+
30+
instance (Eq v) => Eq (Quantity d v) where
31+
(ValQuantity _ v1) == (ValQuantity _ v2) = v1 == v2
32+
33+
instance (Ord v) => Ord (Quantity d v) where
34+
(ValQuantity _ v1) `compare` (ValQuantity _ v2) = v1 `compare` v2
35+
36+
instance Functor (Quantity d) where
37+
fmap f (ValQuantity d v) = ValQuantity d (f v)
38+
39+
----------------------------------------
40+
-- Socker
41+
----------------------------------------
42+
43+
infixl 3 ##
44+
(##) :: v -> Quantity d w -> Quantity d v
45+
v ## (ValQuantity d _) = ValQuantity d v
46+
47+
-- Dummy-värden med matchande värde/typ-nivå dimensioner
48+
-- med en dummy-typ.
49+
50+
length :: Quantity Length Double
51+
length = ValQuantity V.length 1.0
52+
mass :: Quantity Mass Double
53+
mass = ValQuantity V.mass 1.0
54+
time :: Quantity Time Double
55+
time = ValQuantity V.time 1.0
56+
one :: Quantity One Double
57+
one = ValQuantity V.one 1.0
58+
59+
-- Med `##` kan en Quantity med vilken värdetyp som helst skapas
60+
-- med valfri dimension av ovanstående.
61+
62+
-- Om värdetypen ej stöder multiplikation och division kan
63+
-- dessa dummy-värden ändå göras så på, och därför kan man
64+
-- alltid få valfri dimension.
65+
66+
----------------------------------------
67+
-- Aritmetik
68+
----------------------------------------
69+
70+
-- En `Quantity` innehåller något av någon typ. Om och hur addition
71+
-- o.s.v. ser ut för den kan variera, så typen själv ska sköta det.
72+
-- Dessutom kan det var multiplikation mellan olika typer.
73+
74+
class Addable a b c where
75+
doAdd :: a -> b -> c
76+
77+
(+#) :: (Addable a b c) => Quantity d a ->
78+
Quantity d b ->
79+
Quantity d c
80+
(ValQuantity d a) +# (ValQuantity _ b) = ValQuantity d $ doAdd a b
81+
82+
-- Nedan går ej! Blir problem med Vector då. Vet ej varför.
83+
84+
-- Allt "numeriskt" är adderbart
85+
--instance (Num v) => Addable v v v where
86+
-- doAdd = (+)
87+
88+
----------
89+
90+
class Subable a b c where
91+
doSub :: a -> b -> c
92+
93+
(-#) :: (Subable a b c) => Quantity d a ->
94+
Quantity d b ->
95+
Quantity d c
96+
(ValQuantity d a) -# (ValQuantity _ b) = ValQuantity d $ doSub a b
97+
98+
--instance (Num v) => Subable v v v where
99+
-- doSub = (-)
100+
101+
----------
102+
103+
class Multiplicable a b c where
104+
doMul :: a -> b -> c
105+
106+
(*#) :: (Multiplicable a b c) => Quantity d1 a ->
107+
Quantity d2 b ->
108+
Quantity (d1 `Mul` d2) c
109+
(ValQuantity d1 a) *# (ValQuantity d2 b) = ValQuantity (d1 `V.mul` d2) $ doMul a b
110+
111+
--instance (Num v) => Multiplicable v v v where
112+
-- doMul = (*)
113+
114+
----------
115+
116+
class Divisionable a b c where
117+
doDiv :: a -> b -> c
118+
119+
(/#) :: (Divisionable a b c) => Quantity d1 a ->
120+
Quantity d2 b ->
121+
Quantity (d1 `Div` d2) c
122+
(ValQuantity d1 a) /# (ValQuantity d2 b) = ValQuantity (d1 `V.div` d2) $ doDiv a b
123+
124+
--instance (Fractional v) => Divisionable v v v where
125+
-- doDiv = (/)
126+
127+
----------------------------------------
128+
-- Derivering och integrering
129+
----------------------------------------
130+
131+
-- Är själva grejen som finns i en Quantity deriverbar och
132+
-- integrerbar ska Quantityn med den i också vara det.
133+
134+
class Calculable v where
135+
doDif :: v -> v
136+
doInteg :: v -> v
137+
138+
diff :: (Calculable v) => Quantity d v -> Quantity (d `Div` Time) v
139+
diff (ValQuantity d v) = ValQuantity (d `V.div` V.time) $ doDif v
140+
141+
-- Inte det snyggaste...
142+
143+
integ :: (Calculable v) => Quantity d v -> Quantity (d `Mul` Time) v
144+
integ (ValQuantity d v) = ValQuantity (d `V.mul` V.time) $ doInteg v
145+
146+
----------------------------------------
147+
-- Hack
148+
----------------------------------------
149+
150+
-- Eftersom det blir problem med Num som instans av många
151+
-- görs här manuellt för vissa datatyper
152+
153+
instance Addable Double Double Double where
154+
doAdd = (+)
155+
156+
instance Subable Double Double Double where
157+
doSub = (-)
158+
159+
instance Multiplicable Double Double Double where
160+
doMul = (*)
161+
162+
instance Divisionable Double Double Double where
163+
doDiv = (/)
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+

0 commit comments

Comments
 (0)