data Plane = Plane { point :: Point, normal :: Vector Double } data Sphere = Sphere { center :: Point, radius :: Double } class Shape s where intersect :: s -> Ray -> Maybe Point surfaceNormal :: s -> Point -> Vector Double
I have also made both Plane
and Sphere
instances of Shape
.
I'm trying to store spheres and planes in the same list, but it doesn't work. I understand that it shouldn't work because Sphere
and Plane
are two different types, but they are both instances of Shape
, so shouldn't it work? How would I store shapes and planes in a list?
shapes :: (Shape t) => [t] shapes = [ Sphere { center = Point [0, 0, 0], radius = 2.0 }, Plane { point = Point [1, 2, 1], normal = 3 |> [0.5, 0.6, 0.2] } ]
Question: Is it possible to store n number of lists of various types in a single generic list? Answer: Yes, by creating a list of list objects.
A Python list may contain different types! Indeed, you can store a number, a string, and even another list within a single list.
Unlike arrays, an ArrayList can hold data of multiple data types. Elements in the ArrayList are accessed via an integer index.
One is of type (String,Int) , whereas the other is (Int,String) . This has implications for building up lists of tuples. We could very well have lists like [("a",1),("b",9),("c",9)] , but Haskell cannot have a list like [("a",1),(2,"b"),(9,"c")] .
This problem represents a turning point between object-oriented and functional thinking. Sometimes even sophisticated Haskellers are still in this mental transition, and their designs often fall into the existential typeclass pattern, mentioned in Thomas's answer.
A functional solution to this problem involves reifying the typeclass into a data type (usually once this is done, the need for the typeclass vanishes):
data Shape = Shape { intersect :: Ray -> Maybe Point, surfaceNormal :: Point -> Vector Double }
Now you can easily construct a list of Shape
s, because it is a monomorphic type. Because Haskell does not support downcasting, no information is lost by removing the representational distinction between Plane
s and Sphere
s. The specific data types become functions that construct Shape
s:
plane :: Point -> Vector Double -> Shape sphere :: Point -> Double -> Shape
If you cannot capture everything you need to know about a shape in the Shape
data type, you can enumerate the cases with an algebraic data type, as Thomas suggested. But I would recommend against that if possible; instead, try to find the essential characteristics of a shape that you need rather than just listing off examples.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With