Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
data Figure a = forall a. Paint a => Figure a
data Figure = forall a. Paint a => Figure a
Для этого я воспользуюсь расширением ExistentialQuantification, которое позволяет объединять вместе с данными
import System.IO
import Text.Printf
data Figure = Figure
{ paint :: Handle -> IO ()
, say :: String
, circumSquare :: Int
}
base child = child
{ paint = \handle -> hPutStrLn handle $ printf "paint %s S=%d" (say child) (circumSquare child)
}
type Point = (Int, Int)
data Rect = Rect {left, top, right, bottom :: Int}
deriving Show
makeRect :: Point -> Point -> Rect
makeRect (left, top) (right, bottom) = Rect left top right bottom
circle :: Point -> Int -> Figure
circle (x, y) radius = base $ Figure
{ say = printf "circle, radius=%d and centre=(%d,%d)" radius x y
, circumSquare = (2 * radius) ^ 2
}
rect :: Point -> Point -> Figure
rect lt@(left, top) rt@(right, bottom) = base $ Figure
{ say = show $ makeRect lt rt
, circumSquare = (right - left) * (bottom - top)
}
roundrect :: Point -> Point -> Int -> Figure
roundrect lt rt roundR = (rect lt rt)
{ say = printf "round rectangle, %s and roundR = %d" (show $ makeRect lt rt) roundR
}То, что задачу можно решить разными способами, не сомневаюсь.
Что значит «теряются» (если они вон используются в нескольких местах)
Возможно, статье лучше бы подошло название вроде «Эмуляция традиционного ООП на языке Haskell».
В смысле, что их не получить из списка [Figure]
data Figure = forall x . (Typeable x, Paint x) => Figure xdata D = D { ... } или невного класса-типов D это достаточно близкие методы, с небольшой разницей, вроде той, что в случае класса типов, для одного параметра у нас гарантируется наличие единственной реализации функций, чего нету в случае явного словаря. Так-же из функций класса типов мы можем достать сам словарь Dict (c::Constraint) и передавать его явно или восстановить его по прокси переменной. Все тоже самое возможно и с явным словарём, но с большим количеством страданий.
Пример решения типичной ООП задачи на языке Haskell