I've written the following code:
type Mass = Double
type Position = (Double, Double)
type Velocity = (Double, Double)
data Body = Body Mass Position Velocity
data System = System [Body]
renderBody :: Body -> Picture
renderBody (Body mass (x, y) velocity) = object
where
object = translated x y (solidCircle mass)
renderSystem :: System -> Picture
renderSystem (System []) = blank
renderSystem (System (x:xs)) = renderBody(x)<>renderSystem(System(xs))
moveBody :: Double -> Body -> Body
moveBody time (Body mass (x, y) (vx, vy)) = new_body
where
new_x = x vx * time
new_y = y vy * time
new_body = (Body mass (new_x, new_y) (vx, vy))
updateSystem :: Double -> System -> System
updateSystem time (System []) = (System [])
updateSystem time (System(x:xs)) = moveBody time x : updateSystem time System(xs)
I could not understand the following ERROR
What's the problem?
Thanks in advance.
CodePudding user response:
You aren't applying updateSystem time
to a value of type System
; you are applying it to the data constructor System
and a list of Body
values xs
. You need to adjust your parentheses to create the necessary value of type System
.
updateSystem time (System(x:xs)) = moveBody time x : updateSystem time (System xs)
However, you can simply the definition of updateSystem
by using map
on the list that System
wraps.
updateSystem :: Double -> System -> System
updateSystem time (System xs) = System (map (moveBody time) xs)
Extract the value of type [Body]
, map moveBody time
over it to get a new list of Body
's, and rewrap the list as a new System
value.
CodePudding user response:
You can define custom prepending operator for your type, e.g. .:
to wrap list prepending for System
:
type Mass = Double
type Position = (Double, Double)
type Velocity = (Double, Double)
data Body = Body Mass Position Velocity
data System = System [Body]
moveBody :: Double -> Body -> Body
moveBody time (Body mass (x, y) (vx, vy)) = new_body
where
new_x = x vx * time
new_y = y vy * time
new_body = (Body mass (new_x, new_y) (vx, vy))
(.:) :: Body -> System -> System
(.:) b (System x) = System (b : x)
updateSystem :: Double -> System -> System
updateSystem time (System []) = (System [])
updateSystem time (System(x:xs)) = moveBody time x .: updateSystem time (System xs)
You get an error because System
is not a list, so you can not prepend elemens to it just by using :
operator.
You also had a bad notation of System(xs)
instead of (System xs)
, you should to construct System
from list at first, and pass it to functions after this.