Ok, I'll be more concrete
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Database.Persist.TH
import Database.Persist.Sqlite
import Database.Esqueleto
import Control.Monad.IO.Class
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Topic
title String
|]
main :: IO ()
main = do
runSqlite "test.sqlite" $ do
runMigration migrateAll
[Value c1] <- select $
from $ \t ->
do
return countRows
liftIO $ putStrLn $ show (c1 :: Int)
This code causes an error
est2.hs:26:22: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘from’
prevents the constraint ‘(From
SqlQuery SqlExpr SqlBackend a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
That is because the compiler does not know, which table it must use to calculate the count of rows. This thing may be done with a workaround like
[Value c1] <- select $
from $ \t ->
do
orderBy [asc (t ^. TopicTitle)]
return countRows
liftIO $ putStrLn $ show (c1 :: Int)
However, this is awkful, dull and artifical. Is there another, simplier way to fix this code?
The answer is:
We ought to state the table, in which the rows will be counted. The easiest way for this is to use ScopedTypeVariables language extension, and describe locally the types of arguments:
[Value c2] <- select $
from $ \(_ :: SqlExpr (Entity Topic)) ->
do
return countRows