1

Consider following code which can find some set of coordinates:

data Coord = Coord { lat :: Float
                   , lon :: Float
                   }

instance FromRow Coord where
  fromRow = Coord
    <$> field
    <*> field

findSomePoints :: Connection -> Int -> IO [Coord]
findSomePoints = undefined

Then I would like to define data type for named set of coordinates:

data Path = Path { name :: String
                 , points :: [Coord]
                 }

instance FromRow Path where
  fromRow = Path
    <$> field
    <*> -- PROBLEM: would like to call something like `findSomePoints conn field` here...

findPath :: Connection -> Int -> IO Path
findPath = undefined

Unfortunatelly, I don't know how to compose data types with queries (in my case Path with Coord). Is something like this even possible (and how?).

user1518183
  • 4,651
  • 5
  • 28
  • 39
  • What's the SQL query equivalent of your `findPath`? Is there an SQL column with the SQL type `coord[]`, or something shaped more like `(String, Float, Float)`? – bergey Jul 17 '18 at 20:47
  • @bergey: Coordinates and paths are defined in different tables. There exists many-to-many relationship between them. – user1518183 Jul 17 '18 at 21:13
  • Exactly. If the data exists in different tables then it makes little sense to create a `FromRow` instance since the data is not in one row. – Thomas M. DuBuisson Jul 17 '18 at 21:36
  • @ThomasM.DuBuisson Then, how can I create a `Path` data type when the data are logically tied together? Should I have something like `CoordRow` and `PathRow` data types which I then turn into `Path` data type? – user1518183 Jul 17 '18 at 21:43

1 Answers1

2

I would write a data type and a FromRow instance for each table in the database, and separate the database code from the changing-schema code. PathRow and [Coord] are things you can get directly from the DB. makePath :: PathRow -> [Coord] -> Path, to build the nested structure you want, doesn't need to interact with the database at all. Then findPath can be implemented in terms of these pieces.

bergey
  • 3,041
  • 11
  • 17