Хаскельно-кложурное
May. 19th, 2012 10:59 amА вот, тащемта, можно ли и каким образом на хаскеле можно сделать обобщенную функцию такого вида:
На вход подается список функций разных типов, но общей структуры вроде такой:
f :: state -> input -> (new_state,output) (такая функция описывает блок обработки сигналов, с внутренним состоянием, типа фильтра).
На выходе наша обобщенная функция должна выдать нечто такое:
f_all :: state_all -> input_all -> (new_state_all,output_all), где state_all,input_all,output_all - объединение (кортеж) соответственно из всех состояний, входов и выходов переданных на вход функций. То бишь наша функция, из N блоков обработки сигналов делает 1 блок, входы которого - это входы всех составляющих блоков, выходы - выходы составляющих блоков и состояние аналогично.
На кложури с ее макросами и отсутствием строгой системы типов такое делается практически в лоб, за исключением необходимости описывать функции блоков в виде, доступном для преобразования (то ли через рефлекшн, то ли макрос, который опишет функцию с метаданными, то ли есть что-то встроенное). Единственный не совсем ясный вопрос - тип возвращаемого значения из кложурной функции не особо то и узнаешь.
Далее там еще есть необходимость сгенерировать описание соединений (т.е. функция, которая из state_all и части свободных входов генерирует input_all), но над этим пока думать влом)
PS: в общем, забавность ситуации в том, что строгая типизация помогла бы находить ошибки в блоках и соединениях, но с ней возникает необходимость использовать гетерогенные списки, SYB и прочую олеговщину. Причем я в это утыкаюсь регулярно - то с оперденями, то вот сейчас с обработкой сигналов.
На вход подается список функций разных типов, но общей структуры вроде такой:
f :: state -> input -> (new_state,output) (такая функция описывает блок обработки сигналов, с внутренним состоянием, типа фильтра).
На выходе наша обобщенная функция должна выдать нечто такое:
f_all :: state_all -> input_all -> (new_state_all,output_all), где state_all,input_all,output_all - объединение (кортеж) соответственно из всех состояний, входов и выходов переданных на вход функций. То бишь наша функция, из N блоков обработки сигналов делает 1 блок, входы которого - это входы всех составляющих блоков, выходы - выходы составляющих блоков и состояние аналогично.
На кложури с ее макросами и отсутствием строгой системы типов такое делается практически в лоб, за исключением необходимости описывать функции блоков в виде, доступном для преобразования (то ли через рефлекшн, то ли макрос, который опишет функцию с метаданными, то ли есть что-то встроенное). Единственный не совсем ясный вопрос - тип возвращаемого значения из кложурной функции не особо то и узнаешь.
Далее там еще есть необходимость сгенерировать описание соединений (т.е. функция, которая из state_all и части свободных входов генерирует input_all), но над этим пока думать влом)
PS: в общем, забавность ситуации в том, что строгая типизация помогла бы находить ошибки в блоках и соединениях, но с ней возникает необходимость использовать гетерогенные списки, SYB и прочую олеговщину. Причем я в это утыкаюсь регулярно - то с оперденями, то вот сейчас с обработкой сигналов.
no subject
Date: 2012-05-19 08:19 am (UTC)no subject
Date: 2012-05-19 08:42 am (UTC)no subject
Date: 2012-05-19 08:21 am (UTC)?
no subject
Date: 2012-05-19 08:26 am (UTC)Нужно сделать их в определенном смыле одинаковыми. В ООП это делают интерфейсы, в хаскеле должны делать классы типов.
no subject
Date: 2012-05-19 08:28 am (UTC)no subject
Date: 2012-05-19 08:48 am (UTC)no subject
Date: 2012-05-19 10:54 am (UTC)no subject
Date: 2012-05-19 09:02 am (UTC)no subject
Date: 2012-05-19 08:44 am (UTC)no subject
Date: 2012-05-19 11:03 am (UTC)no subject
Date: 2012-05-19 09:10 am (UTC)no subject
Date: 2012-05-19 09:15 am (UTC)f (f1,f2) (input1, input2) = do out1<- f1 input1 out2<- f2 input2 return out1,out2хотя вообще выглядит приемлемо, написать руками таких комбинаторов и посмотреть что получится
no subject
Date: 2012-05-19 09:44 am (UTC)(<^>) :: (s1 -> i1 -> (s1, o1)) -> (s2 -> i2 -> (s2, o2)) -> (s1, s2) -> (i1, i2) -> ((s1, s2), (o1, o2)) f <^> g = \ ~(s1, s2) ~(i1, i2) -> let {~(s1', o1) = f s1 i1; ~(s2', o2) = g s2 i2} in ((s1', s2'), (o1, 2))И потом пишем
f1 <^> f2 <^> f3 <^>...no subject
Date: 2012-05-19 09:46 am (UTC)no subject
Date: 2012-05-19 09:59 am (UTC)no subject
Date: 2012-05-19 10:01 am (UTC)no subject
Date: 2012-05-19 10:11 am (UTC)no subject
Date: 2012-05-19 11:06 am (UTC)no subject
Date: 2012-05-19 11:55 am (UTC)no subject
Date: 2012-05-19 01:10 pm (UTC){-# LANGUAGE TypeOperators #-} data a :. b = a :. b deriving (Eq, Show) (<^>) :: (s1 -> i1 -> (s1, o1)) -> (s2 -> i2 -> (s2, o2)) -> (s1 :. s2) -> (i1 :. i2) -> (s1 :. s2, o1 :. o2) (<^>) f g ~(s1 :. s2) ~(i1 :. i2) = (s1' :. s2', o1 :. o2) where ~(s1', o1) = f s1 i1 ~(s2', o2) = g s2 i2 moo s x = (s+1, x-1) test = (moo <^> moo <^> moo) (1 :. 2:. 3) (5 :. 5 :. 5) == (2 :. 3 :. 4, 4 :. 4 :. 4)Уже юзабельнее, правда? :)
no subject
Date: 2012-05-19 10:21 am (UTC)Функции транслируются практически дословно, только перегрузить надо:
class HeteroList a where heterolength :: a-> Int instance HeteroList () where heterolength _ = 0 instance HeteroList b => HeteroList (a,b) where hetrolength (x,y) = 1+heterolength yno subject
Date: 2012-05-19 10:23 am (UTC)No title
Date: 2012-05-19 10:54 am (UTC)no subject
Date: 2012-05-19 01:40 pm (UTC)no subject
Date: 2012-05-19 01:50 pm (UTC)С хаскелем непонятно. Странные многоуровневые туплы на выходе гетерогенных списков напрягают.
no subject
Date: 2012-05-19 01:55 pm (UTC)no subject
Date: 2012-05-19 01:57 pm (UTC)no subject
Date: 2012-05-19 02:03 pm (UTC)А то я по пути наименьшего сопротивления пока использую Clojure, но очень уж интересно эти задачи в строгой типизации и ленивости оформить. Правда, скажем, с ком-портом на хаскеле получилась ересь - либо tight-coupling (т.е. логика и обмен с внешним миром никак не разделены) либо адовы iteratees и аттопарсеки с багами.
no subject
Date: 2012-05-19 02:40 pm (UTC)no subject
Date: 2012-05-19 02:42 pm (UTC)no subject
Date: 2012-05-20 01:35 am (UTC)