Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List of different types?

Tags:

haskell

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] }          ] 
like image 262
Arlen Avatar asked Oct 16 '11 21:10

Arlen


People also ask

Can a list store different types?

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.

Can a Python list contain different types?

A Python list may contain different types! Indeed, you can store a number, a string, and even another list within a single list.

Can list have different data types C#?

Unlike arrays, an ArrayList can hold data of multiple data types. Elements in the ArrayList are accessed via an integer index.

Can lists in Haskell have different types?

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")] .


1 Answers

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 Shapes, because it is a monomorphic type. Because Haskell does not support downcasting, no information is lost by removing the representational distinction between Planes and Spheres. The specific data types become functions that construct Shapes:

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.

like image 67
luqui Avatar answered Sep 24 '22 21:09

luqui