함수식 JavaScript-편지, 쪽지 및 약속

21044 단어 javascriptfunctional

어떤 사람은 aPromise가 바로 aMonad라고 말한다.aPromise는 aMonad가 아니라는 말도 있다.그들은 모두 틀렸다...그들은 모두 옳다.
이 글을 다 읽으면 FunctorMonad, 그리고 그것들과 Promise 의 유사점과 차이점을 알게 될 것이다.

왜 아무도 명세서를 설명할 수 없습니까?


리스트를 이해하는 데 필요한 필수 어휘를 갖추지 못하면 리스트가 무엇인지 설명하기 어렵다.
나는 두 자석 사이의'무슨 일이 일어났는지'를 묘사해 달라는 요청을 받은 리처드 페만의 이 영상을 좋아한다.
전체 영상은 놀랍고 흥분되지만, 공부에 대한 혐오감이 있다면 6:09로 바로 뛸 수 있다.

I can't explain that attraction in terms of anything else that's familiar to you - Richard Feynman @


따라서 aMonad가 어떤 단어인지 이해하는 데 필요한 몇 가지 절차를 백업해 봅시다.

우리는 편지를 이해할 준비가 되었습니까?


정의: AFunctorMappable 또는 분류에 있는 대상 사이에 비치는 것을 가리킨다.
네, 괜찮아요.아직.그러나 두려워하지 마십시오. FunctorsArray 함수를 사용한 적이 있다면, 당신은 이미 익숙해졌습니다. map
[1, 2, 3].map(x => x * 2) //=> [2, 4, 6]
우리가 aFunctor를 완전히 이해하기 전에 우리는 aMappable가 무슨 뜻인지 이해해야 하고 aCategory가 무엇인지도 이해해야 한다.여기서부터 시작합시다.

카테고리, 객체 및 맵(변형)



Acategory는 하나의 노드(대상)와 상태(함수)로 구성되어 있다.하나의 대상은 숫자, 문자열, URL, 고객, 또는 당신이 원하는 다른 조직 방식일 수 있습니다.(도면의 X, Y 및 Z는 객체입니다.)
Amap는 함수를 사용하여 객체를 다른 객체로 변환합니다.(f, g, fog는 지도).🔍 구글은 대상 사이의 Amap를 AMorphism라고 제시했다.
예: Number Type 방법으로 대상String Type의 대상을 대상toString()으로 전환할 수 있다.
// A map of Number -> String
const numberToString = num => num.toString()
maps를 자신의 대상이나 더 복잡한 대상 유형으로 만들 수 있습니다.
// A map of Number -> Number
const double = num => num * 2

// A map of Array -> Number
const arrayToLength = array => array.length

// A map of URL -> Promise (JSON)
const urlToJson = url =>
  fetch(url)
    .then(response => response.json())
그래서 한 대상은 숫자나 문자열처럼 간단할 수 있다.대상도 사용자 이름, 사용자 API URL, 사용자 API HTTP 요청, 사용자 API 응답, 사용자 API 응답 JSON 등 더욱 추상적일 수 있다.그런 다음 각 객체 간에 맵 또는 변형을 작성하여 원하는 데이터를 얻을 수 있습니다.
상태의 예:
  • 사용자 이름 -> 사용자 API Url
  • 사용자 API Url-> 사용자 API HTTP 요청
  • 사용자 API HTTP 요청-> 사용자 API 응답
  • 사용자 API 응답 -> 사용자 API 응답 JSON
  • 🔍 구글은 Function Composition는 여러 개map 또는 morphisms를 조합하여 새로운 maps를 만드는 방법이라고 제시했다.Function Composition를 사용하면 Username에서 User API Response JSON까지의 지도를 만들 수 있습니다.

    답장


    이제 우리는 Mappable의 뜻을 깨달았고, 마침내 Functor가 무엇인지 알게 되었다.FunctorMappable 또는 범주에 있는 객체 간에 매핑할 수 있는 객체입니다.
    AnArrayMappable이기 때문에 aFunctor입니다.이 예에서 나는 하나Array of Numbers를 하나Array of Strings로 변형시켰다.
    const numberToString = num => num.toString()
    
    const array = [1, 2, 3]
    array.map(numberToString)
    //=> ["1", "2", "3"]
    
    주: aFunctor의 한 특징은 항상 같은 유형Functor을 유지하는 것이다.Array가 포함된 StringsNumbers 또는 다른 대상으로 변형시킬 수 있지만 map는 항상 Array임을 확보할 수 있다.mapArrayNumber로 전환할 수 없습니다.
    우리도 이것Number의 실용성을 다른 대상으로 확장할 수 있습니다!aMappable의 이 간단한 예를 예로 들자.
    const Thing = value => ({
      value
    })
    
    만약 우리가 Thing 비추기를 원한다면, Thing 비추기를 할 수 있는 것처럼, 우리가 해야 할 일은 그것에 Array 함수를 주는 것이다.
    const Thing = value => ({
      value,
      map: morphism => Thing(morphism(value))
    //                 ----- -------- -----
    //                /        |            \
    // always a Thing          |             value to be morphed
    //                         |
    //             Morphism passed into map
    })
    
    const thing1 = Thing(1)               // { value: 1 }
    const thing2 = thing1.map(x => x + 1) // { value: 2 }
    
    이것은 map입니다!사실은 이렇게 간단하다.

    🔍 구글은 우리가 만든 Functor"Thing"의 이름FunctorIdentity이라고 제시했다.

    영수증으로 돌아가다


    때때로 함수는 포장된 값을 되돌려줍니다.Functor와 함께 사용하기가 불편할 수 있습니다. 왜냐하면 Functor를 다른 Functor에 다시 포장하기 때문입니다.
    const getThing = () => Thing(2)
    
    const thing1 = Thing(1)
    
    thing1.map(getThing) //=> Thing (Thing ("Thing 2"))
    
    이 동작은 Array의 동작과 같습니다.
    const doSomething = x => [x, x + 100]
    const list = [1, 2, 3]
    
    list.map(doSomething) //=> [[1, 101], [2, 102], [3, 103]]
    
    이곳이 바로 flatMap에 쓸모가 있는 곳이다.그것은 map와 유사하지만 다른 것은 변형은 포장 값을 집행해야 한다는 것이다.
    const Thing = value => ({
      value,
      map: morphism => Thing(morphism(value)),
      flatMap: morphism => morphism(value)
    })
    
    const thing1 = Thing(1)                          //=> Thing (1)
    const thing2 = thing1.flatMap(x => Thing(x + 1)) //=> Thing (2)
    
    많이 좋아진 것 같아!Maybe에서 Just로 전환해야 할 수도 있습니다. 예를 들어 도구가 부족할 때Nothing에서 유용합니다.
    import Just from 'mojiscript/type/Just'
    import Nothing from 'mojiscript/type/Nothing'
    
    const prop = (prop, obj) =>
      prop in obj
        ? Just(obj[prop])
        : Nothing
    
    Just({ name: 'Moji' }).flatMap(x => prop('name', x)) //=> Just ("Moji")
    Just({}).flatMap(x => prop('name', x))               //=> Nothing
    
    이 코드는 다음과 같이 축소할 수 있습니다.
    const Just = require('mojiscript/type/Just')
    const Nothing = require('mojiscript/type/Nothing')
    const { fromNullable } = require('mojiscript/type/Maybe')
    
    const prop = prop => obj => fromNullable(obj[prop])
    
    Just({ name: 'Moji' }).flatMap(prop('name')) //=> Just ("Moji")
    Just({}).flatMap(prop('name'))               //=> Nothing
    
    🔍 구글은 이런 코드 단축은 currying,partial applicationpoint-free style를 통해 가능하다고 제시했다.
    아마도 너는 더 많은 것을 기대할 것이다. 그러나 한 명세서에 있어서는 이렇다.쪽지는 비출 수도 있고 평탄하게 비출 수도 있다.
    나는 이 점에서 네가 처음에 생각했던 것보다 더 쉬운 여정이라고 생각하기를 바란다.우리는 이미 보도FunctorsMonads, 다음Promise!

    언약


    만약 그 중 어떤 코드가 익숙해 보인다면 Promise의 행동은 mapflatMap와 유사하기 때문이다.
    const double = num => num * 2
    
    const thing1 = Thing(1)             //=> Thing (1)
    const promise1 = Promise.resolve(1) //=> Promise (1)
    
    thing1.map(double)    //=> Thing (2)
    promise1.then(double) //=> Promise (2)
    
    thing1.flatMap(x => Thing(double(x)))          //=> Thing (2)
    promise1.then(x => Promise.resolve(double(x))) //=> Promise (2)
    
    보시다시피 Promise 방법then은 포장되지 않은 값을 되돌릴 때map와 유사하고 flatMap에서 포장할 때Promise와 유사합니다.이렇게 하면 aPromise와 aFunctor와 aMonad는 비슷하다.
    이것도 그것의 차이점이다.
    thing1.map(x => Thing(x + 1))              // Thing (Thing (2))
    promise1.then(x => Promise.resolve(x + 1)) // Promise (2)
    
    thing1.flatMap(x => x + 1) //=> 2
    promise1.then(x => x + 1)  //=> Promise (2)
    
    만약 내가 두 번 값을 포장하고 싶다면 (끼워넣기 Arrays 를 고려하거나 되돌아오는 유형을 제어하고 싶다면, 나는 사용할 수 없다. Promise이렇게 되면 그것은 Functor법률을 위반했고 Monad법률도 위반했다.

    요약

  • AFunctorMappable 또는 분류 중의 대상 사이에 비칠 수 있는 것을 가리킨다.
  • AMonad는 AFunctor와 비슷하지만 분류 간Flat Mappable이다.
  • flatMapmap와 유사하지만, 맵 함수에 되돌아오는 형식을 포장할 수 있습니다.
  • 약속은 FunctorMonad 법률을 위반했지만 비슷한 점이 많다.같지만 다르다.
  • 계속 읽기:
    제 글은 JavaScript에 대한 애정을 보여줍니다.FP가 더 필요하시면 여기나 트위터에 팔로우 해주세요!
    나의 절친한 친구 존이 이 점을 증명해 줘서 고맙다:)

    좋은 웹페이지 즐겨찾기