'null'과 'Maybe'의 개념을 모두 갖는 것이 합리적입니까?


11

C #에서 웹 API 에 대한 클라이언트를 만드는 동안 null두 가지 다른 것을 나타내는 값 과 관련된 문제가 발생 했습니다.

  • 아무 것도 , 예를 들어 할 foo수도 있고 없을 수도 있습니다.bar
  • unknown : 기본적으로 API 응답에는 속성의 하위 집합 만 포함되므로 원하는 추가 속성을 지정해야합니다. 그래서 알 수없는 경우, 해당 건물이 API에서 요청하지 않았 음을 의미합니다.

검색 한 후 Maybe (또는 Option) 유형, 기능 언어에서 사용되는 방법 및 사용자가 값이 없을 가능성에 대해 생각하도록하여 널 역 참조 문제를 어떻게 해결하는지 알아 냈습니다. 그러나 내가 만난 모든 리소스는 nullMaybe로 바꾸는 것에 대해 이야기했습니다 . 나는 세 가지 가치가있는 논리에 대한 언급을 찾았 지만 그것을 완전히 이해하지 못하고 언급 된 대부분의 시간은 "나쁜 일"이라는 맥락에서 왔습니다.

나는 이제 nullMaybe 개념을 모두 알 수 있고 아무것도 나타내지 않는 것이 타당한 지 궁금합니다 . 이것이 내가 읽은 3 가치 논리입니까, 아니면 다른 이름이 있습니까? 아니면 어쩌면 어쩌면에 네스트를 중첩시키는 의도 된 방법입니까?


9
그것은 산만하지 않습니다 null. 완전히 깨진 아이디어입니다.
Andrej Bauer

7
어쩌면 foo와 다른 의미를 가진 어쩌면 foo를 만들지 마십시오. 어쩌면이다 모나드 와 모나드 법칙 중 하나이다 M M xM x같은 의미를 가져야한다.
Eric Lippert

2
Nothing (객체 없음 참조), Null (데이터베이스 null 의미론), Empty (초기화되지 않은 변수) 및 Missing (선택적 매개 변수가 전달되지 않은) Visual Basic의 초기 버전 디자인을 고려할 수 있습니다. 이 디자인은 복잡하고 여러 가지 방식으로 일관성이 없었지만, 이러한 개념이 서로 관련이없는 이유가 있습니다.
Eric Lippert

3
Maybe a+1Maybe Maybe a+1+1UserInput a

12
@EricLippert : " M (M x)M x같은 의미론을 가져야 한다"는 것은 거짓입니다 . 가지고 M = List예를 들면 : 목록리스트 목록과 같은 것이 아니다. 경우 M모나드는, 거기 인 변화 에서 (즉 모나드 승산) M (M x)M x있는 이들 사이의 관계를 설명하고 있지만, "는 동일한 의미를"없다.
Andrej Bauer

답변:


14

null기본 선물로 값이 사방 단지입니다 정말 깨진 아이디어 그래서 잊어.

실제 데이터를 가장 잘 설명하는 개념을 항상 가지고 있어야합니다. "unown", "nothing"및 "value"를 나타내는 유형이 필요한 경우 정확하게 입력해야합니다. 그러나 실제 요구 사항에 맞지 않으면 그렇게해서는 안됩니다. 다른 사람들이 무엇을 사용하고 그들이 제안한 것을 보는 것이 좋지만, 맹목적으로 따를 필요는 없습니다.

표준 라이브러리를 디자인하는 사람들은 일반적인 사용 패턴을 추측하려고하지만 일반적으로 잘 사용하지만 필요한 특정 사항이 있으면 직접 정의해야합니다. 예를 들어, Haskell에서 다음을 정의 할 수 있습니다.

data UnknownNothing a =
     Unknown
   | Nothing
   | Value a

기억하기 쉬운 설명적인 것을 사용해야하는 경우도 있습니다.

data UserInput a =
     Unknown
   | NotGiven
   | Answer a

서로 다른 시나리오에 사용할 10 가지 유형을 정의 할 수 있습니다. 단점은 기존의 라이브러리 함수 (예 :와 같은 Maybe)를 사용할 수 없지만 일반적으로 세부적인 것으로 판명됩니다. 자신 만의 기능을 추가하는 것은 어렵지 않습니다.


당신이 그렇게 철자를 볼 때 완벽하게 이해합니다. 아이디어에 관심이 많습니다. 기존 라이브러리 지원은 보너스입니다. :)
Stijn

많은 언어에서 그러한 유형을 만드는 데 장애가된다면 : /
Raphael

1960 년대 (또는 1980 년대부터 환생)부터 언어 사용을 중단 한 사람들.
Andrej Bauer

@AndrejBauer : 무엇? 그러나 이론가들은 불평 할 것이 없습니다!
트릴

우리는 불평하지 않습니다.
Andrej Bauer

4

내가 아는 null한 C # 의 값 은 유형에 따라 일부 변수에 가능한 값입니다 (맞습니까?). 예를 들어, 어떤 클래스의 인스턴스. 나머지 유형 (예 int: bool등)의 경우 int?또는 bool?대신 변수를 선언 하여이 예외 값을 추가 할 수 있습니다 ( Maybe다음에 설명 할 것처럼 생성자가하는 일입니다).

Maybe함수형 프로그래밍 의 형식 생성자는 주어진 데이터 형식에 대해이 새로운 예외 값을 추가합니다. 따라서 Int정수 유형이거나 Game게임 상태 유형 인 경우 Maybe Int모든 정수에 null (때로는 nothing 이라고 함 ) 값을 더한 값이 있습니다. 에 대해서도 동일합니다 Maybe Game. 여기에는 null값 과 함께 제공되는 유형이 없습니다 . 필요할 때 추가합니다.

IMO,이 마지막 접근 방식은 모든 프로그래밍 언어에 더 좋습니다.


예, C #에 대한 이해가 정확합니다. 그래서 당신의 대답에서 중첩을 제안 Maybe하고 null완전히 떨어 뜨릴 것을 제안 할 수 있습니까?
Stijn

2
내 의견은 언어가 어떻게되어야하는지에 관한 것입니다. 나는 C # 프로그래밍의 모범 사례를 실제로 모른다. 귀하의 경우 가장 좋은 옵션은 @Andrej Bauer가 설명한대로 데이터 유형을 정의하는 것이지만 C #에서는 그렇게 할 수 없다고 생각합니다.
Euge

@Euge : 대수 합계 유형은 고전적인 OO 스타일 하위 유형 지정 및 하위 유형 다형성 메시지 발송으로 (대략) 근사화 할 수 있습니다. 예를 들어 스칼라에서 닫힌 유형 을 허용하기 위해 추가로 꼬임이 수행되는 방식입니다. 타입은 추상 슈퍼 클래스가되고, 타입 생성자는 구체적 서브 클래스가되고, 생성자를 통한 패턴 일치는 구체적인 서브 클래스 나 isinstance테스트 에서 오버로드 된 메소드로 사례를 이동시켜 근사화 할 수 있습니다 . 스칼라는 또한 "적절한"패턴 매칭을 가지고 있으며, C♯는 최근에 간단한 패턴도 얻었습니다.
Jörg W Mittag

"추가 트위스트"I 스칼라에 대한 언급은 "표준"수식어 (로부터 상속 가능 클래스) "가상"과 이외에이다 final(로부터 상속 할 수없는 클래스), 또한 보유 sealedA에 대한, 동일한 컴파일 단위 내에서만 확장 할 수있는 클래스 . 이는 컴파일러가 가능한 모든 서브 클래스를 정적으로 알 수 있으며 (모두 서브 클래스 sealed또는 자체로 제공되는 경우 final) 패턴 일치에 대한 철저한 검사를 수행하므로 런타임 코드로드 및 무제한 상속이있는 언어에서는 정적으로 불가능합니다.
Jörg W Mittag

물론 C #에서 이러한 의미를 가진 유형을 디자인 할 수 있습니다. C #에서는 기본 제공 형식 (C #에서 Nullable이라고 함)을 중첩 할 수 없습니다. int??C #에서는 불법입니다.
Eric Lippert

3

당신은 같은 유형의 조합을 정의 할 수 있다면 X or Y, 당신은 이름의 유형이있는 경우 Null에만 나타내는 null값 (그리고 아무것도를) 다음 모든 유형 T, T or Null실제로에서 그렇게 다르지 않다 Maybe T. 유일한 문제 null는 언어가 유형 TT or Null암시 적 으로 처리하여 null모든 유형에 유효한 값을 만드는 경우입니다 (유형이있는 언어의 기본 유형 제외). 이것은 예를 들어, 함수를받는 함수 String도 받아들이 는 Java에서 발생 합니다 null.

당신이 값의 세트로 및 유형을 치료하는 경우 or세트의 조합으로, 다음 (T or Null) or Null값의 집합을 나타냅니다 T ∪ {null} ∪ {null}와 동일 T or Null. 이러한 종류의 분석 (SBCL)을 수행하는 컴파일러가 있습니다. 주석에서 말했듯이 유형을 도메인으로 볼 때 Maybe TMaybe Maybe T유형을 쉽게 구분할 수는 없습니다 (동시에 유형이 지정된 프로그램에는보기가 유용합니다). 그러나 유형을 대수 표현으로 유지할 수도 있습니다. 여기서 (T or Null) or Null여러 수준의 어쩌면를 나타냅니다.


2
실제로는와 Maybe (Maybe X)같은 것이 중요합니다 Maybe X. Nothing와 같은 것이 아닙니다 Just Nothing. Maybe (Maybe X)와 병용 Maybe X하면 Maybe _다형성 으로 치료할 수 없습니다 .
질 'SO-정지 존재 악마'

1

표현하고자하는 것을 찾아서 표현하는 방법을 찾아야합니다.

먼저 문제 도메인에 숫자, 문자열, 고객 레코드, 부울 등의 값이 있습니다. 둘째, 문제 도메인 값 위에 몇 가지 추가 일반 값이 있습니다. 예를 들어 "아무것도"(알려지지 않은 값), "알 수 없음"(값의 존재 또는 부재에 대한 지식 없음)은 " 무언가 "(확실히 가치가 있지만, 우리는 어느 것을 알지 못합니다). 다른 상황을 생각할 수도 있습니다.

모든 값과이 세 가지 추가 값을 모두 나타내려면 "nothing", "unknown", "something"및 "value"가 포함 된 열거 형을 만들고 여기에서 시작합니다.

일부 언어에서는 경우가 더 간단합니다. 예를 들어, Swift에는 모든 유형 T에 대해 가능한 값 nil과 T의 모든 값을 갖는 "선택적 T"유형이 있습니다. 이는 많은 상황을 쉽게 처리 할 수있게 해주 며 "아무것도 없음"및 " 값". "알 수 없음"및 "값"이있는 경우 사용할 수 있습니다. "아무것도", "알 수 없음"및 "값"을 처리해야하는 경우 사용할 수 없습니다 . 다른 언어는 "null"또는 "maybe"를 사용할 수 있지만 이는 다른 단어 일뿐입니다.

JSON에는 키 / 값 쌍이 포함 된 사전이 있습니다. 여기서 키는 사전에서 누락되었거나 null 값을 가질 수 있습니다. 따라서 저장 방법을 신중하게 설명하면 일반 값과 ​​두 개의 추가 값을 나타낼 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.