Pull to refresh

Comments 21

var a = getData();
if (a != null) {
  var b = getMoreData(a);
  if (b != null) {
     var c = getMoreData(b);
     if (c != null) {
        var d = getEvenMoreData(a, c)
        if (d != null) {
          print(d);
        }
     }
  }
}

А монады-то прикольные штуки! Без них вполне читабельное решение влоб и не такой уж и ад (на haskwell не кодил!) :


var a,b,c,d;
if( 
   ((a=getData())!=null)&&
   ((b=getMoreData(a))!=null)&&
   ((c=getMoreData(b))!=null)&&
   ((d=getEvenMoreData(a,c))!=null)
  )
{
  print(d);
}

Автор немного лукавит)
Тут дело скорее не в самих монадах, а в do-notation.

Нельзя сказать что монады тут совсем не при чем, так как do нотация работает по верх них.
По сути есть две равноправные составляющие, концептуальная и синтаксическая.

При использовании монад всплывают вложенные монады, state-монады с несовместимыми типами, монадические трансформеры....


И можно готовить следующую статью:


Избегание ада монад с помощью ???

Насколько я в курсе, системы эффектов пока еще удел теоретиков. До появления чего-то практичного еще далеко.

МонадТрасформеров
Какой у Вас резкий переход в примерах проверки на null. От JavaScript, CoffeeScript к Haskell. Например на том же JavaScript можно использовать Maybe как функтор, проверку на null и undefined спрятать в метод map. А если еще упростить

function mayBe(value, fn) {
    return value === null || value === undefined ? value : fn(value)
}


или на ES6

const mayBe = (v, f) => v === null || v === undefined ? v : f(v)


Вроде как корректный функтор, который можно использовать при цепочечных вызовах функции, но такого сахара как do конечно не будет. Сидя в JS к прекрасному тоже можно стремится

Haskell как раз используется для примеров потому что есть сахар, а так конечно, Maybe и прочие абстракции можно использовать в любом языке.

проверка на null

Можно использовать старый добрый try-catch:


var a = getData()
try {
  var b = getMoreData(a)
  var c = getMoreData(b)
  var d = getEvenMoreData(a, c)
  print(d)
}
catch (NullPointerException ex) { ... }

for-цикл

Зачем столько скобочек? Без скобочек всё выглядит также, как и со списковым включением:


for (var a in getData()) 
  for (var b in getMoreData(a)) 
    for (var c in getMoreData(b)) 
      for (var d in getMoreData(c)) 
        print(d)

Но тут скорее всего стоит как-то перепроектировать систему и повысить уровень абстракции.

А если в getMoreData(a) произойдет настоящий NullPointer мы его тоже будем замалчивать?)

Можно либо использовать исключения, либо спроектировать без null: если нет данных просто возвращается пустой список.

Хорошо: пустой итератор.

Исключения же дорогие.
Ад проверки на null

да прибудет с вами early return
UFO just landed and posted this here
А как грамотно обрабатывать общение с устройствами, например, при работе с libusb? Сначала ищем устройство, открываем его, потом claim interface, потом опционально, шлём тестовый пакет. На каждом шаге можем обломиться, и для каждого шага потребуется своё освобождение ресурсов. Стандартный подход — в разной степени замаскированный switch+goto по меткам, с ручкой проверкой каждого шага обращения к устройству
Возможно ResourceT (MaybeT IO) поможет вам.
Sign up to leave a comment.

Articles

Change theme settings