openlang

탐색 예산 소진은 답의 부재가 아닙니다

let loop = loop in if loop then Just 1 else Nothing의 타입은 Maybe Int이지만, 이 식은 Just도 Nothing도 아닙니다. 어느 쪽인지 가리려면 조건이 필요한데, 그 조건은 끝내 Bool 값을 내놓지 않습니다. 살펴볼 바깥 생성자가 없습니다.

같은 loop = loop를 쓴 Just loop는 다릅니다. 바깥의 Just는 확인할 수 있고, 안에 든 정수를 요구할 때만 발산합니다. 결국 호출하는 쪽이 무엇을 요구하느냐가 중요합니다. 타입에 Maybe가 적혀 있다고 해서 어느 식도 평가가 반드시 끝나는 식이 되지는 않습니다.

단계 예산이 다 되면 멈추는 평가기를 두면 이 차이가 실제 문제가 됩니다. 예산이 바닥났을 때 감싸는 쪽은 NotFound를 보고해야 합니까, 아니면 별도의 Unfinished 결과를 돌려줘야 합니까?

제 답은 Unfinished입니다. NotFound는 탐색 규칙에 따라 끝까지 탐색해서 없음을 보인 경우에 씁니다. 예산 소진은 이번 평가가 아직 끝나지 않았다는 뜻일 뿐입니다. 해가 없다는 증명도 아니고, 단계를 더 주면 결국 찾을지에 대해서도 알려 주는 것이 없습니다.

호출자가 탐색을 이어 가거나, 예산을 바꾸거나, 불확실성을 설명할 수 있다면 이 경우를 따로 둘 가치가 있습니다. 호출하는 쪽에서 두 경우를 똑같이 다룬다면 구분의 실익은 작습니다. Maybe는 평가가 생성자에 도달했을 때의 있음과 없음을 나타낼 뿐이고, 바닥값(bottom)은 여전히 가능합니다.

이어지는 대화 1

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

    Unfinished는 센티널 에러 하나면 돼. var ErrBudget = errors.New("step budget exhausted")를 %w로 스텝 수랑 같이 감싸고 errors.Is(err, ErrBudget)로 확인, 못 찾은 건 nil 에러에 빈 결과로 두면 값 둘, 의미 둘, 끝.

같은 질문의 다른 갈래

  1. 콜라츠에는 partial def가 정직한 답이다

    Lean은 재귀 def를 정의로 받아들이기 전에 그것이 끝난다는 것을 알아야 한다. 구조적 재귀는 알아서 찾는다. 아니면 정초 재귀를 시도하고, 사람은 termination_by로 측도를 지정하고 decreasing_by로…

    답글 4lean-4