[Haskell] Задачка на тему eDSL.
От: Vintik_69 Швейцария  
Дата: 07.09.09 22:55
Оценка:
Возникла вот такая задачка. Пусть есть тип Rule:

data Rule v where
  Table :: [v] -> Rule v
  Join :: Rule v1 -> Rule v2 -> Rule (v1, v2)

Можно ли сделать так (то есть так определить все недостающее), чтобы выражение вида

r = rule$ do 
  table (arr1 :: [t1])
  table (arr2 :: [t2])
  ...
  table (arrn :: [tn])

транслировалось в

Join
  (Table arr1)
  (Join 
    (Table arr2)
    (Join
      ...
        (Table arrn)))


? Если нельзя, хотелось бы услышать более-менее убедительное обоснование.
Re: [Haskell] Задачка на тему eDSL.
От: Vintik_69 Швейцария  
Дата: 07.09.09 23:04
Оценка:
Здравствуйте, Vintik_69, Вы писали:

V_>? Если нельзя, хотелось бы услышать более-менее убедительное обоснование.


Впрочем, кажется мне, что нельзя, поскольку вне зависимости от количества table-ов монада все равно должна иметь один и тот же тип.
Re: [Haskell] Задачка на тему eDSL.
От: vshabanov http://vshabanov-ru.blogspot.com
Дата: 08.09.09 07:21
Оценка:
Здравствуйте, Vintik_69, Вы писали:

V_>Возникла вот такая задачка. Пусть есть тип Rule:


V_>
data Rule v where
V_>  Table :: [v] -> Rule v
V_>  Join :: Rule v1 -> Rule v2 -> Rule (v1, v2)

V_>Можно ли сделать так (то есть так определить все недостающее), чтобы выражение вида

V_>
r = rule$ do 
V_>  table (arr1 :: [t1])
V_>  table (arr2 :: [t2])
V_>  ...
V_>  table (arrn :: [tn])

V_>транслировалось в

V_>
Join
V_>  (Table arr1)
V_>  (Join 
V_>    (Table arr2)
V_>    (Join
V_>      ...
V_>        (Table arrn)))


V_>? Если нельзя, хотелось бы услышать более-менее убедительное обоснование.


С монадой, скорее всего не выйдет, если только не прятать Prelude и не делать свою монаду.

Но зачем тут монада непонятно, есть же обычные операторы:
r = Table arr1 `Join`
    Table arr2 `Join`
    ...
    Table arrn
Re: [Haskell] Задачка на тему eDSL.
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 08.09.09 08:05
Оценка:
Здравствуйте, Vintik_69, Вы писали:

V_>? Если нельзя, хотелось бы услышать более-менее убедительное обоснование.


Обоснование такое, что ты должен где то накапливать значения разных типов.

Т.е. контейнер, в котором ты это будешь делать, или будет менять свой тип (тогда смотри Beyond Monads, HList, стандартная монада здесь не подходит) или не будет выносить типы элементов в свой тип (Rank-2 полиморфизм), тут можно посмотреть на слабо-типизированный HList или самому построить его аналог. Доставать тогда элементы придётся через cast

Первое — сложно для такой простой задачи (займёт пару десятков строк вместо двух), а второе — сложнее в использовании, т.к. cast надо будет делать уже клиентскому коду.

Поэтому немонадный вариант на комбинаторах выглядит гораздо симпатичнее. А их можно построить какие угодно, например, на классах можно сделать такой

[1,2,3] .+. "abc" .+. [Just 3, Nothing]


Я бы не стал заморачиваться с синтаксисом и сделал просто

table = Table
(.+.) = join
Re[2]: [Haskell] Задачка на тему eDSL.
От: Vintik_69 Швейцария  
Дата: 08.09.09 11:20
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Я бы не стал заморачиваться с синтаксисом и сделал просто


Да, это я пожалуй слишком упростил. Идея была сделать что-то вроде QLC, для чего нужно именовть таблицы. Как-то так:

do
  a <- table [1, 2, 3]
  b <- table [4, 5, 6]
  filter (a+b == 5)
  emit (a/b)


Получив при этом на выходе в каком-то виде AST (а не просто вычислить результат, что просто).
Re[3]: [Haskell] Задачка на тему eDSL.
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 09.09.09 06:56
Оценка:
Здравствуйте, Vintik_69, Вы писали:

V_>Да, это я пожалуй слишком упростил. Идея была сделать что-то вроде QLC, для чего нужно именовть таблицы. Как-то так:


V_>
do
V_>  a <- table [1, 2, 3]
V_>  b <- table [4, 5, 6]
V_>  filter (a+b == 5)
V_>  emit (a/b)


V_>Получив при этом на выходе в каком-то виде AST (а не просто вычислить результат, что просто).


В таком виде построить уже гораздо проще, кажется. Т.к. состояние (тип которого меняется, помнишь?) хранить не надо, в приведённом тобой коде оно передаётсяя в переменных a и b.

Можешь описать проблему?
Re[3]: [Haskell] Задачка на тему eDSL.
От: Аноним  
Дата: 09.09.09 15:36
Оценка: +1
Здравствуйте, Vintik_69, Вы писали:

V_>
do
V_>  a <- table [1, 2, 3]
V_>  b <- table [4, 5, 6]
V_>  filter (a+b == 5)
V_>  emit (a/b)


А чем это отличается от LINQ (или HaskellDB)?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.