2013-02-05 2 views
36

그래서 하스켈 라이브러리 날이하스켈에서는 숟가락이 안전하지 않습니까?

safeHead :: [a] -> Maybe a 
safeHead = spoon . head 

을 수행 할 수 있습니다 spoon라고있을뿐만 아니라 나에게 어떤 경우에는 정말 유용 할 것 같습니다이

>>> spoon True    :: Maybe Bool 
Just True 
>>> spoon (error "fork") :: Maybe Bool 
Nothing 
>>> spoon undefined  :: Maybe Bool 
Nothing 
>>> spoon (let x = x in x) :: Maybe Bool 
<... let's just keep waiting...> 

을 수행 할 수 있습니다, 그러나 그것은 또한 denotational 의미를 위반 (내 이해에) 그것은 의 시맨틱 이미지에서 다른 것들을 구분할 수있게 해주기 때문이다. 이는 연속성에 의해 정의 된 의미를 가지고 있기 때문에 throw/catch보다 강력합니다.

>>> try $ return (error "thimble") :: IO (Either SomeException Bool) 
Right *** Exception: thimble 

그럼 내 질문은 : 누군가가 숟가락을 사용하여 유형 안전을 파괴 할 수 있습니까? 위험 할 가치가있는 편의? 또는 더 현실적으로, 그것을 사용하는 것이 프로그램의 의미에 대한 누군가의 자신감을 침식 할 수있는 합리적인 방법이 있습니까?

+3

당신은 무슨 위험을 말하고 있습니까? 순정 주의자가 공포에 반동 할 수 있을까? –

+0

좋은 질문입니다,이게 정말 유용 할 것 같습니다. –

+9

@RobertHarvey 아무리 위험한 일이 아니지만, 순도를 위반하면 모듈 캡슐화를 둘러싼 행동이나 트릭에 대한 잘못된 기대로 이어질 수 있습니다.나는 실제 코드에서'spoon'을 사용하는 것보다 행복 할 것이지만, 나는 그것이 Haskell의 의미에 위배된다는 것을 오늘 알았다. –

답변

36

무언가를 사용하면 무해한 리팩터처럼 보이는 것을하면 프로그램의 동작을 바꿀 수있는 까다로운 부분이 있습니다.

f h x = h x 
isJust (spoon (f undefined)) --> True 

그러나 아마이 책에서 가장 흔한 하스켈 변환을하고, ETA의 수축, f에,

f h = h 
isJust (spoon (f undefined)) --> False 

에타 수축이 이미 보존 의미하지 않습니다 제공합니다 모든 종과 경적없이,이입니다 seq의 존재 때문에; 그러나 숟가락 η 수축이 없으면 종료 프로그램을 오류로만 변경할 수 있습니다. 스푼 η 축소는 종료 프로그램을 다른 종료 프로그램으로 변경할 수 있습니다.

공식적으로 spoon이 안전하지 않은 방법은 non-monotone on domains입니다 (따라서 그에 따라 정의 된 기능도 될 수 있음). 없이는 spoon 모든 기능은 단조입니다. 그래서 기술적으로 당신은 공식적인 추론의 유용한 속성을 잃게됩니다.

이것이 중요한 경우의 실제 예가 나와 있습니다 (읽으십시오 : 은 실제 생활에서 문제가 될 가능성이 거의 없습니다.) 악용을 시작하지 않으면 읽기가 어려울 수 있습니다. 예 : undefined 자바 프로그래머가 사용하는 방법 null)

+3

이것은 제가 찾던 것입니다. 필자는 non-monotonicity 속성에 연결하지 않았는데, 이는 사용 규칙의 일부가 항상 'Nothing'응답을 서브 시스템 실패의 종류로 간주해야 함을 의미합니다. –

12

unsafeCoercespoon으로 쓸 수 없습니다. 그것은 정확하게 보이지 않는만큼 부정하며, 하스켈의 의미를 정확하게 나타냅니다. 그러나 segfault 또는 이와 유사한 항목을 만드는 데는 사용할 수 없습니다.

그러나 하스켈 의미를 위반하여 으로 코드를 추론하기가 더 어렵습니다. 스푼이 포함 된 safeHead은 반드시 직접 작성된 safeHead보다 효율적이지는 않습니다.

+1

예, 'unsafeCoerce'를 쓰는 방법이 없다는 것을 알았지 만별로 걱정스럽지는 않습니다. 모듈 경계 등을 위반하는 방법이 있는지 알고 싶다는 것 이상입니다. 실수로 의도적으로 악의적 인 코드가 잘못 오용 될 수있는 무언가 ... 내가 뺨에 혀 같은 종류의 질문에 글을 썼지 만. –

관련 문제