Здравствуйте, nikov, Вы писали: N>Могли бы вы привести самый красивый или элегантный кусок кода на Haskell, который вам приходилось видеть или писать?
Охх... Самый красивый — не самый красивый — хз, но мне вот этот как-то запомнился больше всего (давно хаскель в руки не брал). http://rsdn.ru/Forum/message/3272029.1.aspx
Здравствуйте, nikov, Вы писали:
N>Могли бы вы привести самый красивый или элегантный кусок кода на Haskell, который вам приходилось видеть или писать?
Насчет самого красивого не скажу, но приведу понравившийся код:
-- быстрая сортировка
qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)
-- все перестановки элементов списка
permutations [] = [[]]
permutations xs = [x:ps | x <- xs, ps <- permutations (xs\\[x])]
-- числа Фибоначчи
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
-- "поиск в ширину" в дереве; находит первый элемент, удовлетворяющий предикату testFun
-- дерево задается корнем (root) и функцией генерации дочерних узлов (genChildsFun)
widthSearch :: a -> (a -> [a]) -> (a -> Bool) -> a
widthSearch root genChildsFun testFun = fromJust $ find testFun $ concat $ iterate (concatMap genChildsFun) [root]
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>nikov,
N>>Могли бы вы привести самый красивый или элегантный кусок кода на Haskell, который вам приходилось видеть или писать? LCR>
Здравствуйте, thesz, Вы писали:
V>>Намекаешь на сложность восприятия рекурсивных типов?
T>Это не рекурсивный тип в твоём понимании, что ты высказал ниже.
Это рекурсивный тип в понимании рекурсивного типа, а не в том, что ты увидел ниже.
В моем примере был простейший вариант, а если делать "по-модному", то можно и так:
abstract class S<A> {
public abstract A Value1 {get; }
public abstract S<A> Value2 {get; } }
А на практике так же есть всевозможные градиенты от первого варианта ко второму, и на одной из разновидностей никому не плохеет, однако. Вся твоя наблюдаемая "катастрофичность" восприятия тут может разве что крыться в незнании о ленивости по-умолчанию в Хаскеле, ну дык это лечится одной фразой.
T>Не говоря уж о том, что next должен иметь тип Computation<A> *next.
V>>>Намекаешь на сложность восприятия рекурсивных типов? T>>Это не рекурсивный тип в твоём понимании, что ты высказал ниже. V>Это рекурсивный тип в понимании рекурсивного типа, а не в том, что ты увидел ниже.
Здравствуйте, thesz, Вы писали:
V>>Это рекурсивный тип в понимании рекурсивного типа, а не в том, что ты увидел ниже.
T>Короче, ты решил стоять на своём. Это небезопасно для здоровья, и даже использовалось в качестве пыток, ты об этом знаешь?
Ну ты же не ответил на вопрос, вместо этого попытался обсуждать терминологию, а это действительно бывает опасно.
Еще одна вещь, которая меня на днях очень впечатлила:
В классе Foldable t есть методы:
foldMap :: Monoid m => (a -> m) -> t a -> m
foldr :: (a -> b -> b) -> b -> t a -> b
Каждый из них имеет реализацию по умолчанию, выражающуюся через другой метод (таким образом, при определении инстанса класса достаточно реализовать любой из них). Так вот foldr очень красиво выражается через foldMap. Если вы ее не видели или не помните, то рекомендую попробовать написать ее самостоятельно.