курсов по Хаскелю (и даже начал вторую), и вроде немного приноровился оперировать некоторыми понятиями. 
                  
                  
                  И вот, давеча, дошло дело до собеседования (которое будет через неделю), и я решил попробовать решить задание для лайвкодинга и понял, что не знаю, как использовать структуры и типы данных адекватно (без хардкода на десятки паттерн мэтчей). 
                  
                  
                  Условия написаны крайне неудовлетворительно, но, как я понял, это просто задумка, которую должен развивать интервьюер. 
                  
                  
                  
                  
                  
                  Смысл задания в следющем: есть парковочные места (Small, Compact, Large) и транспорт (Motorcycle, Car, Van). Для расположения мотоцикла можно использовать любое место (и оно будет считаться занятым) etc. - принцип понятен. Для расположения, например, фургона (вэна) можно использовать 3 обычных места (ну, или, например, 6 маленьких), или, собственно, одно большое. 
                  
                  
                  
                  
                  
                  Я начал делать и вот что получилось:
                  
                  
                  
                  
                  
                  {-# LANGUAGE GADTs #-}
                  
                  
                  
                  
                  
                  module Parking where
                  
                  
                  
                  
                  
                  data Vehicle = Motorcycle | Car | Van deriving (Show, Eq)
                  
                  
                  
                  
                  
                  data SpotType = Small | Compact | Large deriving (Show, Eq)
                  
                  
                  
                  
                  
                  data Spot a where
                  
                  
                    Spot :: {spotType :: SpotType, vehicle :: Vehicle} -> Spot a
                  
                  
                    -- CompactSpot :: {spotType :: SpotType, vehicle :: Vehicle} -> Spot a
                  
                  
                    -- LargeSpot :: {spotType :: SpotType, vehicle :: Vehicle} -> Spot a
                  
                  
                    deriving (Show, Eq)
                  
                  
                  
                  
                  
                  data ParkingLot a where
                  
                  
                    ParkingLot :: {spots :: [Spot a]} -> ParkingLot a
                  
                  
                  
                  
                  
                  testData :: ParkingLot a
                  
                  
                  testData =
                  
                  
                    ParkingLot
                  
                  
                      [ Spot Small Motorcycle,
                  
                  
                        Spot Compact Car,
                  
                  
                        Spot Large Van,
                  
                  
                        Spot Small Motorcycle
                  
                  
                      ]
                  
                  
                  
                  
                  
                  Собственно, я попытался было ввести ограничения по располагаемым на парковочном месте объектам (по заветам ChatGPT), но получилось не очень.
                  
                  
                  
                  
                  
                  data Spot a where
                  
                  
                    SmallSpot :: (a ~ 'Small, b ~ 'Motorcycle) => {spotType :: SpotType, vehicle :: Vehicle} -> Spot (a,b)
                  
                  
                    ...
                  
                  
                  
                  
                  
                  И даже если бы это сработало, остаётся неясно, каким образом ввести, условно, расширение, позволяющее использовать, например, 3 обычных места в качестве одного - для фургона.
                  
                  
                  
                  
                  
                  Дисклеймер: мои знания крайне рандомные, так как я самоучка во всех смыслах (собственно, это, наверно, и подводит).
                  
                  
                  
                  
                  
                  Вопрос, правильно ли я думаю, что надо вводить данные ограничения именно в структурах данных? Если да, то покажите, пожалуйста, как (если нет - всё равно покажите как это работает, если такое имеет место быть). И чтобы мне такое поделать, чтобы пройтись по этому пласту знаний (может статьи, книги подскажете).
                  
                  
                  
                  
                  
                  А ещё хочу, чтобы вы немного пояснили: я на автомате написал Spot a хотя, можно было просто сделать Spot. Звучит глупо, но я понимаю общую параметризацию только на примере списка, и вопрос: я сделал общую параметризацию для того, чтобы в будущем мог вводить алгебраические описания типа функтора, аппликатива etc.?
                  
                  
                
в чём именно задание? сформулировать эти правила в виде компайл-тайм ограничений?
Ну, собственно, по ссылке есть задача: условия написаны неоднозначно. Есть типы транспорта и типы парковочных мест. Моя идея была в том, чтобы сделать из них тип с тремя конструкторами, который не позволит, например, на маленькое место поставить фургон.
Обсуждают сегодня