왜 fpts 옵션이 이렇습니까?

24877 단어

tl;박사


중첩 시 Option 는 기존 nullable 값보다 더 많은 데이터를 포함합니다.

카탈로그

  • The problem

  • Something Option can do that Nullable Can't
  • undefined can't nest
  • Option saves the day!
  • Metadata and Data: Sum Types vs Union Typs
  • Set Theory
  • Category Theory
  • Conclusion
  • 문제

    Option 좋아요. - 몬드 실례와 파이프 조수 함수 등이 있습니다. - 하지만 null 또는 undefined 를 사용해야 할 때 불편할 수 있습니다.ArrayRecord 도우미 함수와 유형 클래스 인스턴스를 사용하여 표준 Typescript 배열 및 레코드 유형을 간단히 입력하고 출력할 수 있습니다.
    import * as A from 'fp-ts/Array'
    import * as R from 'fp-ts/Record'
    import { pipe } from 'fp-ts/pipeable'
    
    const arr: number[] = pipe(
      [1, 2, 3],
      A.map(n => n * 2),
    )
    const rec: Record<string, number> = pipe(
      {a: 1, b: 2, c: 3},
      R.map(n => n * 2),
    )
    
    Option는 유사한 흔한 패턴(nullables을 표시하지만, O.fromNullable를 사용해서 null로 변환할 수 있는 값을 다시 사용해야 합니다O.toUndefined.
    import * as O from 'fp-ts/Option'
    const nullablenum: number | undefined = ...
    const opt: number | undefined = pipe(
      nullablenum,
      O.fromNullable,
      O.map(n => n * 2),
      O.toUndefined
    )
    
    "Nullable"또는 Option 사용 여부에 관심이 있으시다면 제 조립 문서를 보십시오.
    그런데 저희가 왜 선택을 해야 돼요?왜 Option 로 정의되지 않습니까?이 유형을 위해 monad를 실현하는 실례는 매우 간단하다.
    import { identity } from 'fp-ts/function'
    
    type Option<A> = A | undefined
    export const OptionMonad = {
      of: identity,
      chain: <A, B>(fa: Option<A>, f: (a: A) => Option<B>): Option<B> => fa !== undefined ? f(fa) : undefined,
    }
    
    무슨 좋은 점이 있습니까?이것이 설마 생활을 더욱 가볍게 하지는 않겠는가?type Option<A> = A | undefinedO.none같은 거 아니야?

    일부 정의되지 않은 것들은 할 수 있지만, 옵션은 할 수 없다


    이 사람을 고려한 예:
    const firstTerm: number | undefined = 3
    const secondTerm: number | undefined = undefined
    const sum: number | undefined = firstTerm
      ? secondTerm
        ? firstTerm + secondTerm
        : undefined
      : undefined
    
    우리는 이렇게 사용할 수 있다.
    if (sum !== undefined) {
      console.log(`sum: ${sum}`)
    } else {
      console.error(`Not enough terms`)
    }
    // output: Not enough terms
    
    만약 우리가 부족한 용어에 따라 다른 오류 출력을 인쇄하려고 한다면 어떻게 해야 합니까?
    if (sum === undefined) {
      // does 'firstTerm' exist or not?
    }
    

    Nullable은 중첩할 수 없습니다.


    이상적인 경우 다음과 같은 유형의 서명이 필요할 수 있습니다.
    const sum: number | undefined | undefined = firstTerm
      ? secondTerm
        ? firstTerm + secondTerm
        : undefined
      : undefined
    
    믿든 안 믿든 네 마음대로 해라, 이것은 매우 좋다!그러나 이 두 개undefined는 같다.저희가 뭐가 뭔지 어떻게 알아요?
    컴파일러가 백그라운드에서 이런 유형을 통일했기 때문이다.undefined, number, undefined, undefined 세 가지 가능한 반환 상황이 있다.Typescript는 이러한 경우union를 수용하고 이중화undefined를 제거하고 number | undefined로 플랫화합니다.
    비어 있는 값의 경우 flatten the identity function 입니다.

    시간 절약 선택!


    import { flow } from 'fp-ts/function'
    import { pipe } from 'fp-ts/pipeable'
    import * as O from 'fp-ts/Option'
    
    const firstTerm: O.Option<number> = O.some(3)
    const secondTerm: O.Option<number> = O.none
    const sum: O.Option<O.Option<number>> = pipe(
      firstTerm,
      O.map(firstTerm => pipe(
        secondTerm,
        O.map(secondTerm => firstTerm + secondTerm)
      )),
    )
    pipe(
      sum,
      O.fold(
        () => console.error(`First term doesn't exist`),
        O.fold(
          () => console.error(`Second term doesn't exist`),
          sum => console.log(`sum: ${sum}`)
        ),
      ),
    )
    // output: Second term doesn't exist
    
    여기서 신기한 점은 sum 유형:
    const sum: O.Option<O.Option<number>>
    
    Option둥지!이것은 우리가 조작이 실패한 곳을 정확하게 추적할 수 있다는 것을 의미한다.

    메타데이터 및 데이터: 총 유형 및 결합 유형


    Gabriel Lebec Option 우리에게 준 fp-ts slack channel 위에서 나에게 설명하다

    separation between meaningful layers (metadata vs. data)


    여기서, 우리의 메타데이터는 우리에게 조작이 성공했는지 여부를 알려 준다.Optionsum type(또는 표기 연합 또는 판별 연합)으로 실현되기 때문에 엔진 뚜껑 아래에 메타데이터와 데이터는 다음과 같이 각각 저장된다.{ _tag: 'Some', value: 3 }는 메타데이터이고 _tag는 데이터이다.이것은 우리로 하여금 서로 다른 데이터를 한데 묶고 그것과 관련된 메타데이터를 분리할 수 있게 한다.
    한편, value과의 연합은 메타데이터와 데이터를 결합시킨다.
    const separatedMetadata: O.Option<O.Option<number>> = {
      _tag: 'Some',
      value: {
        _tag: 'None'
      }
    }
    const coupledMetadata: number | undefined = undefined
    
    undefined 은 "실패"메타데이터이자 "결과 없음"데이터입니다.
    반면 값undefined은'성공'의 메타데이터이자'3'의 데이터이다.
    const separatedMetadata2: O.Option<O.Option<number>> = {
      _tag: 'Some',
      value: {
        _tag: 'Some',
        value: 3
      }
    }
    const coupledMetadata2: number | undefined = 3
    
    유형3O.None이 비슷해 보일 수 있지만 undefined보다 인코딩된 정보가 더 많다.이것은 { _tag: 'None' } 반드시 두 개의 값 중의 하나이어야 하기 때문에 undefined 이런 상하문이 없기 때문이다._tag의 초기 사례에서 undefined는 두 개의 서로 다른 메타데이터를 분할할 수 없이 함께 칠하여 정보를 잃어버렸다.

    집합론


    병합 유형은 두 집합의 병합일 뿐이다
    A.∪ B
    구화 유형의 모든 원소는 반드시 하나label'l'가 있어야 한다
    A+B=({lA}×A)∪ ({lB}×B)
    이 레이블은 객체 소스의 컬렉션을 나타냅니다.그것은 모든 물체가 어디에서 왔는지 기억하도록 허락한다.
    우리는 위의 등식에서 볼 수 있듯이 유형과 병합 유형은 같지만 반대는 아니다.
    이것이 바로 라벨 연맹이라는 단어의 유래다.sum 에서 이 레이블은 undefined 필드입니다.
    중첩 시 Option 필드 도움말 _tag 성공 또는 실패 여부를 기억하십시오.

    범주론


    또 다른 Nestability를 생각하는 방법은 형식의 일원적 정확성의 측면에서 고려하는 것이다.
    우리가 앞에서 정의한 _tag 실례를 기억하십니까?비록 그의 유형은 정확하지만, 실제로는 그것이 정확한monad 실례가 아니다. - 실패했다left identity law
    const f = (_: undefined): number => 1
    const leftTerm = OptionMonad.chain(OptionMonad.of(undefined), f)
    const rightTerm = f(undefined)
    const leftIdentity = leftTerm === rightTerm
    console.log(`${leftTerm} vs. ${rightTerm}`)
    console.log(`left identity passes? ${leftIdentity}`)
    // undefined vs. 1
    // left identity passes? false
    
    일원좌신분처리 편평화와소포1 - 기본적으로 그것은 문제를 제기했다. "Option편평화와종OptionMonad소포는 시종 서로 상쇄됩니까?"
    우리의 예에서 답은 부정적이다. 왜냐하면 우리의 chain 은 신분 함수이기 때문에 실제로는 어떤 것도 포장하지 않는다.of 함수는 전개할 수 있는 포장이 없기 때문에 of 모든 값에 대한 단락이 있어야 합니다. 설령 chain 함수가 우리가 통과하기를 원하는 값일지라도.undefined값을 직접 호출undefined해서 f로 되돌아오기 때문에 우리의 행동이 일치하지 않습니다.
    이것은 간단한 방식으로 단자 법칙(또는 그 중의 하나)의 실용성과 공사 응용을 증명하였다.왼쪽 표지는 리스트가 의미 있게 끼워 넣을 수 있도록 확보했다.
    다음에 자신이 undefined 좌절되었다는 것을 발견할 때, 이 점을 기억하세요. 표기되지 않은 데이터를 화려한 끼워 넣은 수학적으로 1원 포장된 값처럼 들리고 있습니다.

    결론


    이것은 왜 number 구화 유형으로 실현되었는지에 대한 견해를 제공하고 장려로서 적당한 범주 이론 리스트의 실제 장점에 대한 견해를 제공하기를 바란다.
    한두 달 전, 나는 Nullable의monad 실례가 유효할 수도 있고, 표시된 유니온보다 더 간단한 인터페이스를 가지고 있다는 것을 발견했다.나는 매우 흥분해서 거의 도서관에 내가 발견한 문제를 복구해 달라는 요청을 했다.
    그러나 내가 이렇게 하기 전에, 나는 이'문제'가 사실상 잘못이라는 것을 재확인하는 것이 현명하다고 생각한다.나는 fp-ts slack channelO.fromNullable 표기의 연합으로 실현되었느냐고 물었다.너는 위의 링크를 클릭하여 사람들이 제공한 멋진 설명을 볼 수 있다.기쁘게도 나는pull 요청을 실현하는 것을 피했다. 반대로 나는 학습 과정에서 방향을 바꾸었고 이것은 나로 하여금 이 글을 쓰게 했다.
    나는 그곳에서 기본적인 문제를 제기하고 진지하게 대할 수 있다는 공공 포럼의 계발을 받았다.나는 당신이 OptionOption 이완 채널here에 가입하는 것을 건의합니다. 특히 함수식 프로그래밍을 깊이 이해하는 데 관심이 있다면.
    지역사회는 나를 지지하고 선량하며 더 좋은 개발자가 되도록 도와준다.
    (편집:) slack 커뮤니티에서 계속 저를 지지해 주세요!감사Monoid Musician는 범주론이 아니라 집합론에 속하고 유형과 병합은 단자법칙에 부합되지 않는다고 지적했다.
    어떤 사람들은 포장 은유를 좋아하지 않는다. 그들은 그것이 소수의 명세서만 묘사하고 나중에 더 많이 도입될 때 더 많은 혼동을 초래할 뿐이라고 정확하게 단언한다.다음은 전형적인 추문들(,)이다. 
    그러나 논문What we Talk About When we Talk About Monads은'형식'과'실시'차원의 지식을 제외하고 이러한 은유는 개념을 완전하게 이해하는 데 필요하다고 주장했다.

    좋은 웹페이지 즐겨찾기