Я совершенно не знаком с Haskell (и, в более общем плане, функциональным программированием), так что простите меня, если это действительно базовый материал. Чтобы получить больше, чем вкус, я пытаюсь реализовать в Haskell некоторые алгоритмические материалы, над которыми я работаю. У меня есть простой модуль Interval
, который реализует интервалы на линии. Он содержит типHaskell новичок по типам
data Interval t = Interval t t
функции помощника
makeInterval :: (Ord t) => t -> t -> Interval t
makeInterval l r | l <= r = Interval l r
| otherwise = error "bad interval"
и некоторые вспомогательные функции относительно интервалов.
Здесь мой интерес заключается в многомерных интервалах (d-интервалах), те объекты, которые состоят из d интервалов. Я хочу отдельно рассмотреть d-интервалы, которые являются объединением d непересекающихся интервалов на линии (множественный интервал) от тех, которые являются объединением d-интервала на d отдельных линиях (интервал трека). С различными алгоритмическими процедурами в виде, я думаю, было бы неплохо иметь два различные типа (даже если оба список интервалов здесь), такие как
import qualified Interval as I
-- Multilple interval
newtype MInterval t = MInterval [I.Interval t]
-- Track interval
newtype TInterval t = TInterval [I.Interval t]
для обеспечения различных проверок здравомыслия, например,
makeMInterval :: (Ord t) => [I.Interval t] -> MInterval t
makeMInterval is = if foldr (&&) True [I.precedes i i' | (i, i') <- zip is (tail is)]
then (MInterval is)
else error "bad multiple interval"
makeTInterval :: (Ord t) => [I.Interval t] -> TInterval t
makeTInterval = TInterval
Теперь я добираюсь до сути, наконец! Но некоторые функции, естественно, связаны как с несколькими интервалами, так и с интервалами. Например, функция order
вернет количество интервалов в несколько интервалов или интервал дорожки. Что я могу сделать? Добавление
-- Dimensional interval
data DInterval t = MIntervalStuff (MInterval t) | TIntervalStuff (TInterval t)
не помогает, так как, если я хорошо понимаю (поправьте меня, если я ошибаюсь), я должен был бы написать
order :: DInterval t -> Int
order (MIntervalStuff (MInterval is)) = length is
order (TIntervalStuff (TInterval is)) = length is
и называют order
в order (MIntervalStuff is)
или order (TIntervalStuff is)
когда is
это MInterval
или TInterval
. Не так уж и здорово, это выглядит странно. Я также не хочу дублировать функцию (у меня есть много функций, которые связаны как с множественными, так и с дорожками, а также с некоторыми другими определениями d-интервалов, такими как множественные интервалы длины и длины трека).
У меня осталось ощущение, что я совершенно не прав и пропустил какой-то важный момент о типах в Haskell (и/или не могу забыть здесь достаточно о программировании OO). Итак, совершенно новый вопрос, каким было бы лучшим способом в Haskell справиться с такой ситуацией? Должен ли я забыть о введении MInterval
и TInterval
и идти только с одним типом?
Большое спасибо за вашу помощь,
Garulfo
Как раз в сторону, 'foldr (&&) True == и'. – Nefrubyr