Re: Применятель комбинаторов
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 20.02.07 12:33
Оценка:
Здравствуйте, deniok, Вы писали:

D>И что-то не нравится мне, что в mod1 нужен такой перебор по арностям комбинаторв. Есть идеи, как это сделать поэлегантнее?


mod1 :: Cmb -> Cmb
mod1 (Cmb c)  = (Cmb c)
mod1 ((Cmb "I") :# t) = t
mod1 ((Cmb c) :# t) = (Cmb c) :# mod1 t
mod1 ((Cmb "W") :# t :# s) = t :# s :# s
mod1 ((Cmb "K") :# t :# s) = t
...


или

data Cmb = Cmb String
         | Cmb :# Cmb
                 | Apply String (Cmb -> Cmb)

cmbI = Apply "I" id
cmdK = Apply "K" (\c -> Apply "" (\_ -> c))

mod1 ((Apply _ ap) :# c) = ap c


Правда, вывод применения будет не такое очевидный, как у тебя. Можно сделать фильтр вывода, например по имени того, что apply-им, т.е. если имя "", то не выводить. Можно навернуть mod1 так, что если самый левый в цепочке :# будет Apply, то применять пока имя не будет непустым, как то так (пишу сходу, не проверяю)

mod1 (l :# r) | isApply comb = fullApply (apply comb first) chain
    where (comb, rev_chain) = breakAp (l :# r)
              first:chain = reverse rev_chain

isApply Apply{} = True
isApply _ = False

breakAp (l :# r) = let () = let (comb,chain) = breakAp l in (comb,r:chain)
breakAp comb = (comb, [])

fullApply comb [] = comb
fullApply (Apply "" ap) (first:chain) = fullApply (ap first) chain
fullApply comb chain = foldl (:#) comb chain
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.