Я хотел бы оценить простой граф вычислений. Я был в состоянии написать код, чтобы сделать это для вычисления графа, где каждый нетерминал узел имеет два зависимостей (и это может быть тривиально распространено на любое фиксированное число зависимостей)Оценка строго типизированного графика вычислений с произвольным числом зависимостей на узел
{-# LANGUAGE ExistentialQuantification #-}
module Graph where
-- Have:
data Node a =
forall u v . CalculationNode { f :: u -> v -> a
, dependencies :: (Node u, Node v) }
| TerminalNode { value :: a }
eval :: Node a -> a
eval (CalculationNode f (d1, d2)) = f (eval d1) (eval d2)
eval (TerminalNode v) = v
three :: Node Int
three = TerminalNode 3
abcd :: Node String
abcd = TerminalNode "abcd"
seven :: Node Int
seven = CalculationNode (\ s i -> i + length s) (abcd, three)
Вопрос заключается в том: как Я распространяю этот код так, чтобы заметки могли принимать произвольное количество зависимостей?
Что-то вроде:
data Node a =
forall u_1 u_2 ... u_n . CalculationNode { f :: u_1 -> u_2 -> ... -> u_n -> a
, dependencies :: (Node u_1, Node u_2, ... , Node u_n) }
| TerminalNode { value :: a }
eval :: Node a -> a
eval = ?
Я подозреваю, что это требует некоторого typefamily/hlist колдовство, но я даже не знаю, с чего начать. Решения и подсказки приветствуются.
В случае, если вы хотите, библиотека, которая поддерживает этот вид материала: 'дженерики-sop' обеспечивает' Prod' как 'NP' и' mapProd' как 'hmap'. Кроме того, 'vinyl' предоставляет' Prod' как 'Rec' и' mapProd' как 'rmap'. – kosmikus
Это выглядит великолепно, и хотя мне понадобится время, чтобы обернуть вокруг меня голову, он обязательно получит галочку. @kosmikus - спасибо за указание библиотек, где я могу найти эти вещи. Является ли '(: ->)' доступным в хаке? – obadz
@obadz Я не знаю никаких пакетов, которые его содержат, и, к сожалению, я не смог использовать ни одну из поисковых систем Haskell для поиска типа семейства по типу. – user2407038