하마
6k
2017-02-27 15:56:40 작성 2017-02-28 09:37:03 수정됨
4
3934

[스칼라] Future 와 모나드


스칼라에서 Future 를 통해서 모나드를 알아보는 글을 퍼왔습니다. 이 글을 읽어도 모나드가 무엇인지 모두 알수는 없습니다만  군더더기 없이 굉장히 깔끔하게 쓰여진 글이더군요. 누구의 글과는 다르게..( 뜨끔 합니다;;;) 

카카오톡 - 스칼라의 Future 로 알아보는 모나드 


p.s

스칼라 동시성 프로그래밍은 보통  아래와 같은 기술들로 이루어 졌습니다.

- Future

- Await

- Promise

- Observable 

- Akka streamming 

- async, await

- scalaz 의 task 


아래 책에 자세히 잘 나옵니다. 



참고로 스칼라의 Future 자바스크립트의 Promise 와 비슷합니다.
(근데 스칼라는 Promise 가  따로 있어요~)





4
  • 댓글 4

  • Jet Li
    102
    2017-02-28 00:24:47 작성 2017-02-28 00:49:51 수정됨

    매우 조잡하고 간단하게  monad에 대해  부연설명을 한번 드려보겠습니다. 


    함수형 프로그래밍은 함수가 일등 시민(?)이고 코드의 조작이 주로 함수단위의 조합과 분리로 행해집니다.

    이 방식으로 프로그래밍을 하고자 할 때 다음과 같은 문제가 생깁니다.


    scala에서 일반적인 함수는 다음과 같이 조합하면 됩니다.  

    def f : Int => Boolean =
      (a:Int) => if (a > 0) true else false
    
    def g : Boolean => String =
      (b:Boolean) => if (b) "Good" else "Bad"
    
    //  f와 g 함수의 조합  g ∘ f  
    def h(c:Int) : String = g(f(c))
    //  또는 
    def h : Int => String = f andThen g 


    하지만 값을 입력받고 결과를 추가적인 context에 에워싸서 값을 돌려주는, 

    예들들어 Int값을 받고 Option[Int], List[Int], Future[Int]등을 결과값으로 리턴하는 함수들은

    andThen으로 조합이 되지않는 문제가 발생합니다.



    아래의 fOptgOpt 조합 함수인 gOptfOpt는 어떻게 조합 해야 할까요?

    def fOpt : Int => Option[Boolean] =
      (a:Int) => if (a > 0) Some(true) else if (a < 0) Some(false) else None
    
    def gOpt : Boolean => Option[String] =
      (b:Boolean) => if (b) Some("Good") else Some("Bad")
    
    //  fOpt와 gOpt 함수의 조합  gOpt ∘ fOpt  
    def hOpt : Int => Option[String] = fOpt(_) ??? gOpt

    고려할 요소를 생각해보면,  fOpt의 결과값이 Some(x)인가 None인가에 따라 
    gOpt의 적용 여부가 달라지는 로직이 존재해야 됩니다.
    이러한 로직은 context에 둘러싸인 값을 다루는데에서 반복적으로 나타납니다.
    이런  종류의 로직을 추상화시켜 단순화시킬 수 있는 어떤 수단이 있을까요?
    그 수단이 바로 Monad입니다. 다시 말해서, 선행 함수의 결과값context와 후속 함수의 입력값과의
    연관성을 추상화 시킨 인터페이스 (java의 인터페이스가 아닌 일반적 의미에서) 입니다. 
    이것을 이용해서 추가 context를 가진 함수도 일반 함수처럼 조합할 수 있게 되는것이지요.

    scala에서는 이러한 monadic 로직이 flatMap을 통해 기본으로 구현 되어 있습니다.
    object OptionflatMap 소스코드를 보시면 실제로 하는일이 None인지를 판단해서
    인자로 받은 함수를 적용 할지를 판단해서 값을 리턴하는것을 볼 수 있습니다.

    //  fOpt와 gOpt 함수의 조합  gOpt ∘ fOpt  
    def hOpt = fOpt(_) flatMap gOpt
    
    
    // Option object의  flatMap 소스 코드  내부
    object Option {
    
        def flatMap[B](f: A => Option[B]): Option[B] =
            if (isEmpty) None else f(this.get)
    }

  • 하마
    6k
    2017-02-28 10:27:00 작성 2017-02-28 11:17:58 수정됨

    이렇게 깔끔하게 포인트만 추려내서 설명해 주시다니~@@

    정보 공유 감사합니다.


    * 참고사항 

    def hOpt = fOpt(_) flatMap gOpt  // 타입추론을 못하면서 에러 !

    or

    def hOpt (x: Int) = fOpt(x) flatMap gOpt   // 가능 

    or

    def hOpt = fOpt(_:Int) flatMap gOpt  // 좋습니다.


    p.s

    모나드가 먼지 좀 더 느껴보고 싶은  분들은 아래 링크(한글블로그)들을 방문해서 쭈욱 읽어보세요.

    https://github.com/enshahar/BasicFPinScala/blob/master/Intermediate/Monad.md

    https://github.com/enshahar/BasicFPinScala/blob/master/Intermediate/Monad_Rules.md

    http://www.haruair.com/blog/2986

    http://blog.seulgi.kim/2015/07/what-is-monad.html

    모나드가 무엇인지 이해함으로써 함수형프로그래머가 되겠다는 것은 "악기란 무엇인가?"를 이해하면 모든 악기의 연주자가 될 수 있으리라는 믿음과 같다. 즉 모나드를 이해하는것과 프로그래밍을 잘하는것과는 별개의 문제.  - Fallacy (2015)

    아래는 우스개) 
    함수형 세계에서 가장 많이 출판되는 세가지글은 

    1. 모나드란 무엇인가?  류의 튜토리얼  
    2. 모나드 튜토리얼을 작성하기위한 지침 튜토리얼 
    3. 모나드를 알 필요 없습니다. 류의 모나드 비판(?) 튜토리얼 


  • 최첨단
    1k
    2017-02-28 12:47:55

    모나드가 사실 뭔지 몰라요. 그런데 지금까지는 그냥 잘 아는척 쓰고 있습니다. 주변 분들을 보면 다를 그렇게 쓰더라고요. ㅋㅋㅋ

    (그래도 언젠가는 위키피디어에 있는 내용을 모두 이해 하고 싶기는 합니다.)

    하마님의 좋은 글 늘 고맙습니다.

  • Jet Li
    102
    2017-02-28 19:38:52

    하마님 오류수정 감사합니다.👍


    최첨단님 위키의 모나드 설명은 순수 카테고리 이론 측면에서 설명한 거라 열심히 공부해서

    모두 이해한다 하더라도 "뭐야 이거였어?"라는 느낌으로 공허감이 오실 수 있습니다.  😅

  • 로그인을 하시면 댓글을 등록할 수 있습니다.