25구현 문제
타입클래스 인스턴스 구현하기
1. 문제와 수정 범위
Priority#(RequestKind) instance는 네 enum label에 의미상 우선순위를 각각 정의해야
합니다. starter의 구현은 모든 값에 0을 반환하므로 Refresh만 우연히 맞고, 나머지 값은
계약을 위반합니다. 낮은 순서부터 Refresh, Read, Write, Reset이며 결과는 각각
0부터 3까지입니다.
수정 범위는 Priority#(RequestKind) 안의 priorityOf 본문뿐입니다. 타입클래스 선언,
완성된 Bool instance, requestPriority와 proviso, mkTop 구조는 그대로 두세요.
2. starter 읽기와 결과 예측
instance를 수정하기 전에 다음 관계를 읽어 보세요.
RequestKind의 선언 순서는Reset,Read,Refresh,Write입니다.priorityOf는RequestKind값을 받아 2비트 결과를 반환합니다.Boolinstance는 같은 멤버 이름에 별도의 동작을 제공합니다.requestPriority(Write)에서는 인자 타입RequestKind에 따라 proviso가Priority#(RequestKind)instance를 요구합니다.
현재 코드에는 필요한 instance가 존재하고 멤버의 타입도 맞으므로 컴파일됩니다. 그러나
임시 본문이 항상 0을 반환하므로 공개 실행에서 Write의 결과는 0입니다. 수정한 뒤에는
같은 관찰에서 2가 표시되어야 합니다. 이 문제는 instance를 찾지 못한 오류가 아니라, 선택된
instance의 동작 오류입니다.
3. 최소 구현과 완료 조건
기존 priorityOf 안에서 네 label을 모두 구분하세요. 선언 순서와 요구한 우선순위가
다르므로 enum의 비트 인코딩을 우선순위로 사용하면 안 됩니다. case를 쓰면 각 label의
의미가 명시적으로 드러나지만, 완료 조건은 특정 문법이 아니라 전체 동작입니다.
다음 관찰을 모두 만족해야 합니다.
Refresh,Read,Write,Reset은 각각 0, 1, 2, 3을 반환합니다.False와True는 기존Priority#(Bool)을 통해 각각 0과 3을 반환합니다.- 두 타입 모두 변경하지 않은
requestPriority와 proviso를 사용합니다.
화면에 표시되는 Write만 2로 만드는 수정은 완료가 아닙니다. 네 RequestKind 값의 대응이
모두 맞아야 하며, Bool instance의 동작도 유지되어야 합니다. enum과 Bool instance를
고르는 runtime selector는 추가하지 마세요. 인자 타입이 시뮬레이션 전에 instance를
결정합니다.
4. 단계형 힌트
힌트 1: 오류 위치 구분하기
proviso와 instance header는 이미 유효합니다. 수정 대상은 generic dispatch가 아니라
구체적인 RequestKind 멤버 구현입니다.
힌트 2: 분기 기준 정하기
RequestKind 값을 기준으로 분기하고 네 enum label을 모두 처리하세요. 각 결과는 label의
인코딩 값이 아니라 문제에 제시된 의미상 순위에서 정합니다.
힌트 3: 전체 범위 확인하기
네 label이 추론 과정에 한 번씩 포함되었는지 확인해 보세요. 2비트 반환 타입은 0부터 3까지를 모두 표현할 수 있습니다.
5. 추가 실험
필수 구현이 끝나면 mkTop에 표시할 인자를 잠시 Write에서 True로 바꿔 보세요. 실행
전에는 결과 3을 예측합니다. 실행으로 확인한 뒤 원래 호출을 복원하세요. 같은 다형 함수가
proviso 변경이나 runtime dispatch 없이 인자 타입에 따라 기존 Bool instance를 선택한다는
사실을 확인할 수 있습니다.