Не мог бы кто-нибудь объяснить мне, как мне следует исправить подпись этого типа?

#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)