Динамическая отправка, интеллектуальные конструкторы, возможно, шаблон Haskell?

#haskell #existential-type #template-haskell #dynamic-dispatch

#haskell #экзистенциальный тип #шаблон-haskell #динамическая отправка

Вопрос:

Я смотрю на HaskellWiki> Экзистенциальный тип# Механизм динамической отправки.

И я думаю, в Template Haskell должен быть способ принять эту часть:

 class Shape_ a where
    ...

type Radius = Double
data Circle = Circle Radius

instance Shape_ Circle where
    ...
  

и автоматически выводит эту часть:

 -- derive the data type
data Shape = forall a. Shape_ a => Shape a

-- derive smart constructors similar to the original constructor
circle :: Radius -> Shape
circle r = Shape (Circle r)
  

Это было сделано в Template Haskell? Можно ли это сделать в TH? Можно ли сделать что-то подобное в простом старом Haskell без необходимости выписывать все интеллектуальные конструкторы вручную? Потребуется ли для этого специальный препроцессор, более мощный, чем TH?

Ответ №1:

Это определенно можно сделать с помощью шаблона Haskell. Очень мало того, что невозможно. Но я считаю, что написание шаблонного кода Haskell довольно болезненно.

С GHC 7.4 и расширением ConstraintKinds вы также можете абстрагировать его часть:

 data Some :: (* -> Constraint) -> * where
    Some :: forall cls a. cls a => a -> Some cls

type Shape = Some Shape_

instance Shape_ Shape where
    perimeter (Some a) = perimeter a
    area (Some a) = area a

shape :: Shape_ a => a -> Shape
shape = Some
  

Автоматизация этих объявлений экземпляров — это еще одна вещь, которую может сделать TH, и, насколько мне известно, только TH.

Комментарии:

1. Другими словами, «Да! Шаблон Haskell может это сделать! » 🙂 Спасибо за совет по ConstraintKinds, это довольно круто.

2. Да… Я бы показал вам код, если бы не упомянутая причина. Ручной анализ и построение АСТ — это очень весело.

Ответ №2:

Как насчет добавления метода в Shape_ класс с реализацией по умолчанию:

 toShape :: a -> Shape
toShape = Shape
  

Для получения информации об уровне техники см. Exception Класс и SomeException тип данных.

Комментарии:

1. Я надеюсь на автоматически производные интеллектуальные конструкторы; это все равно потребует от меня написания circle r = toShape (Circle r) и т. Д.