Pull to refresh

Comments 24

Наверное всё-таки:
  1. instance MyEq Bool where
  2.     myEqual True True = True
  3.     myEqual False False = True
  4.     myEqual _ _ = False

:)
В Dive Into Python «list comprehension» перевели как «расширенная запись списков».
Да, спасибо, исправил.

Насколько я узнал, название идёт из axiom of comprehension, что по-русски обычно переводят как «аксиома выделения». Но «выделение списков» как-то не звучит.
мне кажется, наиболее понятная аналогия — «конструкторы списков»
У Душкина переведено как «списочные включения».
>> foo :: (Eq a, Show a, Read a) => a -> String -> String
Как это сделать, например, в С++/C#?


ну, в C# можно с помощью generics и type constraints:

public void Foo (T a) where T : IEquable, IShowable, IReadable
Подозревал об этом, когда писал, но не проверил.
Буду иметь в виду.
с generics вообще много фана, т.к. они похожи на typeclasses

вот, к примеру:

var Orders = new List<Order>() 

//code to populate orders omitted 
var q = Orders  
    .Where(x => x.OrderDate < DateTime.Now)  
    .OrderBy(x => x.OrderDate)  
    .Select(x => new {ID = x.OrderID, Date = x.OrderDate})


чем не монада? :)

( devhawk.net/2008/07/30/Monadic+Philosophy+Part+2+The+LINQ+Monad.aspx )
разумеется, тут ещё заслуга extension methods
И это только третий дотнет, увы.
Имхо, проводить аналогию между монадами и вычислениями — плохая идея, хоть и популярная. У меня, например, сразу возникло непонимание: вычисления — это функции, чем они не подходят? Мне было бы понятнее, если бы монады представляли как контейнеры.
А функции подходят, только это частный случай, когда результат предыдущего вычисления просто передаётся следующей функции.
Код забыл:
runIdentity $ do
    x <- return 5
    y <- return $ x + 4
    return $ y * 2
Вот об этом я и говорю — своершенно неочевидно, что нам мешает написать:
x = 5
y = x + 4
Честно, не нашёлся, что ответить.
Что мешает нам использовать напрямую класс в ООП и заставляет нас описывать какой-то интерфейс?
Ничего не мешает, это просто удобная абстракция. В частном случае можно вызывать функции. Но это один частный случай.
Мешает то, что таким образом мы лишаем себя возможности легко подставлять разные имплементации. И об этом стоит четко говорить при объяснении ООП. А здесь в чем проблема?
Причем с функциями, возвращающими Maybe не показателен?
Показателен, как и с ио, состоянием, массивами, ошибками, итд — но это все воспринимается как частные случаи. Типа — придумали библиотеку и под нее все подгоняем.

Нужно более общее восприятие. Например, начнем с функтора. Зачем он нам нужен? Чтобы навешивать дополнительную логику к применению функции.

Если x — простое значение, мы пишем «f x»; если x — функтор, мы пишем «fmap f x». Что оно делает?
Для x :: [a] — применяет f ко всем элементам x.
Для x :: Maybe a — применяет f к содержимому, если оно есть, Nothing остается Nothing.
Для x :: IO a — применяет f к будущему значению, которое мы получим в результате ввода.
Для x :: Tree a — применяет f к значениям во всех узлам дерева.
Для x :: (твой тип) a — сам определишь, что оно делает.

Однако что делать, если функция возвращает значение, которое само по себе функтор? Мы получим нагромождение функторов — [[a]], Maybe Maybe a, IO IO a, Tree Tree a. Таким образом, полезно иметь также функцию, которая схлопывает двойной функтор в одинарный — join.

Аналогично, нам нужна функция для помещения значения в функтор — return.

Вот функтор с join и return — и есть монада. А про bind можно и потом рассказать, с примерами почему он удобен.
Это ближе к теории категорий, но зато дальше от do-нотации. В итоге всё равно придётся рассказывать про вычисления, которые комбинируется bind'ом неявно внутри do и что там можно использовать любую монаду.
Какое объяснение проще понять — не знаю, надо опрос проводить, лично мне были наиболее понятны те, что приведены по ссылкам.
а мне наоборот кажется более удобным представлять себе монаду, как контейнер содержащий в себе не значение, но «замороженный процесс» его вычисления. Это во многом согласуется с тем, что теоретик-первопроходец Eugenio Moggi в далёком 89 году предложил использовать монады именно для формализации «понятия вычисления» (notion of computation).

вот как, например, представить себе монаду Cont, как контейнер?
Контейнер, содержащий CPS-функцию, насколько я понимаю.
ну дык, следующий раз так и не настал?
Времени сейчас совсем немного, а дел навалом, а я хотел прежде доделать до конца, а потом последовательно расписывать. Так что всё будет, как только так сразу.
Сори что не по теме, перечитывал статью — наткнулся на «значниею», поправьте плиз.
Sign up to leave a comment.

Articles