나는 극도로 무서운 기능인 unsafeCoerce를 사용하고있는 상황에 처해있다. 다행스럽게도 중요한 것은 아니지만이 기능을 안전하게 사용하는지, 아니면 다른 사람들이 알고있는이 특정 문제를 해결할 다른 방법이 있을지 궁금합니다. 주의 할이것은 unsafeCoerce를 안전하게 사용합니까?
data Token b = Token !Integer
identical :: Token a -> Token b -> Bool
identical (Token a) (Token b) = a == b
data F a = forall b. F (Token b) (a -> b)
retrieve :: Token b -> F a -> Maybe (a -> b)
retrieve t (F t' f) = if identical t t' then Just (unsafeCoerce f) else Nothing
두 가지 추가를,이 토큰은 내가 그들을 위해 정수의 공급이 고유한지 확인하는 데 사용하는 모나드 내에서 사용되는 것이 있습니다
내가 가진 코드는 다음과 같이이다 (즉, 나는 동일한 토큰을 두 번 만들지 않는다). 나는 또한 ST 모나드와 같은 방식으로, 정량화 된 그림자 타입 변수를 사용하여 (모듈에서 노출 된 메소드 만 사용된다고 가정 할 때) 토큰을 반환 할 방법이 없다는 것을 확인한다. F)를 형식 오류없이 모나드에서 제거합니다. 토큰 생성자도 공개하지 않습니다.
내가 볼 수있는 한, 안전하지 않은 상인의 안전한 사용법이라고 생각한다. 나는 강요하고있는 가치가 실제로 나는 그것을 강요하고 있지만 잘못된 것일 수 있습니다. 나는 또한 Data.Typeable을 사용해 보았지만 멋지게 작동했다. 그러나 지금은 Typeable 제약을 피하려고 노력하고있다. 특히 gcast는 여러면에서 비슷한 방식으로 뭔가를하는 것으로 보이며, 토큰을 구별해야한다. 같은 타입의 다른 Fs.
도움/조언을 해주셔서 감사합니다.
이것은'cast'를 구현하기 위해'unsafeCoerce'를 사용하는'Data.Typeable'과 매우 흡사합니다. –
그것은 그와 매우 흡사합니다. 사실 iirc는 질문의 마지막 단락의 후반 부분에서 많은 것을 말했습니다. 어쨌든 고마워. – DarkOtter
'cast'를 효과적으로 복사한다면'unsafeCoerce'의 사용법은 안전 합니다만 컴파일러가'typeOf' /'TypeRep'을 생성하지 못하게됩니다. 토큰에'Integer' 대신'TypeRep'을 사용하는 것을 고려할 수 있습니다. –