2011-11-04 2 views
7

나는 다음과 같은 기능을 썼다 :GHC는 ST 모나드 코드를 형식 변수를 통합 할 수 없다고 거부합니까?

(.>=.) :: Num a => STRef s a -> a -> Bool 
r .>=. x = runST $ do 
v <- readSTRef r 
return $ v >= x 

을하지만 컴파일하려고 할 때 나는 다음과 같은 오류 있어요 :

Could not deduce (s ~ s1) 
from the context (Num a) 
    bound by the type signature for 
      .>=. :: Num a => STRef s a -> a -> Bool 
    at test.hs:(27,1)-(29,16) 
    `s' is a rigid type variable bound by 
     the type signature for .>=. :: Num a => STRef s a -> a -> Bool 
     at test.hs:27:1 
    `s1' is a rigid type variable bound by 
     a type expected by the context: ST s1 Bool at test.hs:27:12 
Expected type: STRef s1 a 
    Actual type: STRef s a 
In the first argument of `readSTRef', namely `r' 
In a stmt of a 'do' expression: v <- readSTRef r 

사람이 도와 줄 수 있습니까?

답변

12

이것은 의도 한 것과 같습니다. STRefrunST 한 번만 유효합니다. 그리고 외부 STRefrunST의 새로운 실행에 넣으려고합니다. 그것은 유효하지 않습니다. 이는 순수한 코드에서 임의의 부작용을 허용합니다.

그래서 시도하는 것은 달성하기가 불가능합니다. 디자인에 의해!

7

당신은 ST 컨텍스트 내에서 유지해야합니다

(.>=.) :: Ord a => STRef s a -> a -> ST s Bool 
r .>=. x = do 
v <- readSTRef r 
return $ v >= x 

(그리고 HAMMAR가 지적한대로, 당신은 제공하지 않습니다 NumOrd typeclass가 필요 >=를 사용합니다.)

+1

참고이 있음 제약 조건은'Num'가 아니라'Ord'이어야하기 때문에 여전히 타입 체크를하지 않을 것입니다. – hammar

+0

감사합니다. – dave4420