2014-09-03 2 views
3

Учитывая this Scala code:Как преобразовать эту карту/карту карты в понимание в Clojure?

def compute2(maybeFoo: Option[Foo]): Option[Int] = 
    maybeFoo.flatMap { foo => 
    foo.bar.flatMap { bar => 
     bar.baz.map { baz => 
     baz.compute 
     } 
    } 
    } 

, который затем переводится на это для понимания:

def compute2(maybeFoo: Option[Foo]): Option[Int] = 
    for { 
    foo <- maybeFoo 
    bar <- foo.bar 
    baz <- bar.baz 
    } yield baz.compute 

Мой вопрос Как преобразовать эту карту/flatMap в для понимания в Clojure?

Предположения:

  • Если возможно, я хотел бы использовать идиоматические Clojure (т.е. mapcat), чтобы представить это, а не algo.monads/fluokitten библиотек. Но если это лучший способ сделать это (я открыт для обучения), то используйте это.

ответ

2

Вы, вероятно, не будет использовать Option в Clojure, но если объекты внутри коллекции что-то, как это должно работать:

(let [maybe-foo [{:bar [{:baz [(fn [] 42)]}]}]] 
    (for [foo maybe-foo 
     bar (:bar foo) 
     baz (:baz bar)] 
    (baz))) 
;=> '(42) 

(let [maybe-foo [{:bar nil}]] 
    (for [foo maybe-foo 
     bar (:bar foo) 
     baz (:baz bar)] 
    (baz))) 
;=> '() 

(let [maybe-foo nil] 
    (for [foo maybe-foo 
     bar (:bar foo) 
     baz (:baz bar)] 
    (baz))) 
    ;=> '() 
+0

Ok - так что, если мы хотим использовать 'Option' - тогда мы» вернитесь к 'algo.monads' http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/ - это правильно? – hawkeye

+0

@hawkeye, чтобы использовать 'for', вам нужно, чтобы объекты были обернуты в последовательности, если это не нормально, вам, вероятно, придется использовать' algo.monads' (или сворачивать свои собственные). – ponzao

+0

Хорошо, вы говорите, что для понимания в основном цикл for с блоком let-block в верхней части? – hawkeye