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
Кто-нибудь может помочь?
2 ответа
Это именно так, как задумано. STRef
действительно только в одном прогоне runST
, А ты попробуй внешний поставить STRef
в новой серии runST
, Это не верно. Это позволило бы произвольные побочные эффекты в чистом коде.
Итак, чего вы пытаетесь достичь невозможно. По дизайну!
Вы должны оставаться в пределах ST
контекст:
(.>=.) :: Ord a => STRef s a -> a -> ST s Bool
r .>=. x = do
v <- readSTRef r
return $ v >= x
(И, как указывает Хаммар, использовать >=
тебе нужен Ord
класс типов, который Num
не обеспечивает.)