openlang

private union case, smart constructor를 썼는데 remove 후에도 `Colors []`가 나와요?

안녕하세요 여러분,

저는 작은 swatch 에디터를 만들고 있는데, 세 가지 case로 된 palette union이 있어요. 새로 편집을 시작하면 NotEntered, 의도적으로 비운 경우는 Empty, 그리고 Colors는 리스트를 가져요. case들을 private으로 만들고 ofColors만 공개했고, ofColors []는 Empty를 돌려줘요. 저는 컴파일러가 Colors []를 만들 수 없게 해 줄 거라고 생각했어요.

스크립트로 돌린 세션(새로 시작, blue 추가, blue 제거, Save)에서 Save가 "empty (chosen)" 대신 "0 colors"를 출력해요. Reset은 제대로 동작해요. Rider에도 밑줄이 안 뜨고 빌드도 깨끗해요.

처음엔 List.filter를 의심했고, 그다음엔 Rider가 global.json과 다른 SDK를 쓰는 건가 싶어서 터미널에서 다시 빌드해 봤어요. 결과는 똑같았어요.

원인이라고 생각하는 함수는 이거예요:

let remove (name: string) (p: Palette) =
    match p with
    | Colors cs -> Colors(cs |> List.filter (fun c -> c.Name <> name))
    | other -> other

혹시 private은 Palette.fs 밖에서만 검사돼서, 같은 모듈 안에서는 Colors []를 마음대로 만들 수 있는 건가요? access control page를 보면 그런 것 같기도 한데 확신은 없어요. 그렇다면 add와 remove도 ofColors를 거치게 하는 게 보통의 해결 방법인가요, 아니면 타입 자체가 잘못된 건가요? 그냥 리스트 하나와 entered 플래그를 쓰는 게 더 간단할지도 궁금해요.

감사합니다, Oskar

영어에서 번역원문 보기

이어지는 대화 1

서로의 근거를 따라
  1. 고유 링크

    깔끔하게 정리해 줘서 고마워요, Oskar. privacy에 대한 생각은 맞는 것 같아요. 정의된 모듈 안에서는 constructor가 보이니까 remove가 Colors []를 마음대로 만들 수 있어요. Haskell도 숨긴 constructor가 똑같이 동작해서 F#에만 있는 일은 아니에요.

    해결책을 고르기 전에 하나만 알고 싶어요. Save는 실제로 뭘 기준으로 match하나요? Colors cs case에서 개수를 출력하게 되어 있다면, 그 값이 어떻게 만들어졌든 Colors []면 전부 "0 colors"라고 출력할 거예요. fresh에서 add로 넘어가는 단계는 ofColors를 거치나요, 아니면 Colors를 직접 만드나요? 단계 순서(add, remove, Save)에 따라 최종 값을 만드는 함수가 달라지니까 물어보는 거예요.

    remove를 ofColors로 거치게 하면 add도 똑같이 해야 할까요? 그리고 Colors가 non-empty 리스트를 가지게 하는 방법은 왜 제외했는지도 궁금해요.

    영어에서 번역원문 보기

같은 질문의 다른 갈래

  1. 읽기 전용 List<Int>는 스냅샷인가요?

    List<Int>는 읽기 전용 뷰예요. 스냅숏이 아니에요. 그 참조로 어떤 연산을 호출할 수 있는지 알려 줄 뿐, 뒤에 있는 컬렉션이 그대로 남는다고 약속하지는 않아요. val owned = mutableListOf(2, 4…

    답글 4최근 활동 kotlin
  2. 측정 단위를 값싼 ID로 쓰기

    정수 ID에 단일 케이스 유니온 대신 측정 단위를 써 보고 있는데, 더 퍼지기 전에 다른 의견을 듣고 싶어요. CustomerId of int는 [<Struct>]를 붙이지 않으면 할당이 생기고, 쓸 때마다 생성자나 매치를…

    답글 1최근 활동 fsharp
  3. discriminated union 전에 JSON 검증하기

    백업 호스트에서 상태 덤프를 읽어서 한 줄씩 출력하는 작은 툴이에요. 각 파일은 items가 있는 ready이거나, message가 있는 failed여야 해요. 호스트 네 대는 잘 출력돼요. db-02는 이런 내용이에요 (c…

    답글 4최근 활동 typescript