#haskell #types #persistent #yesod
#haskell #типы #постоянный #yesod
Вопрос:
Вот код, я попытался разрешить вывод типа для определения типа функции. Во время компиляции кода происходит сбой во время выполнения.
Ambiguous type variables `b0', `m0' in the constraint:
(PersistBackend b0 m0) arising from a use of `isFree'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: isFree testDay
In an equation for `it': it = isFree testDay
:t isFree
isFree :: PersistBackend b m => C.Day -> b m Bool
>isFree day = do
match <- selectList [TestStartDate ==. day,
TestStatus !=. Passed,
TestStatus !=. Failed] []
if (L.null match) then (liftIO $ return True) else (liftIO $ return False)
Ответ №1:
ghci сообщает вам, что он не знает, какие выражения типа выбирать для b
и m
. Все, что вам нужно сделать, это сказать это,
isFree testDay :: Foo Bar Bool
В реальных программах эти переменные типа обычно определяются на сайте использования, поэтому вам редко приходится указывать там тип выражения. В приглашении ghci контекст отсутствует, поэтому вам часто приходится это делать.
Не связанный, последняя строка isFree лучше будет return $ L.null match
Комментарии:
1.
liftIO (return x)
вероятно, простоreturn x
. Не уверен, существуют ли какие-либо «законы» дляMonadIO
MonadTrans
экземпляров or, но если бы они были, это наверняка было бы одно. =)2. Не уверен, какими должны быть Foo и Bar .
3. D’oh. Конечно, спасибо. Процитирую мою любимую подпись: «Если я не видел дальше, то это потому, что я стоял по следам гигантов».
4. @MichaelLitchard: все, что вы хотите, до тех пор, пока есть
instance PersistBackend Foo Bar
.
Ответ №2:
«Во время компиляции кода происходит сбой во время выполнения». маловероятно, что ошибка при предоставлении типа этой функции.
Что означает «сбой»?
Ответ №3:
Это смущает. С одной стороны, эта проблема заставила меня углубиться в глубины монад Yesod. С другой стороны, на этот вопрос для меня уже был дан ответ. Когда вы выполняете действие с базой данных, передайте результат в runDB следующим образом.
>isFree day = do
match <- runDB $ selectList [TestStartDate ==. day,
TestStatus !=. Passed,
TestStatus !=. Failed] []
if (L.null match) then (liftIO $ return True) else (liftIO $ return False)