[Haskell-cafe] Selda: confused about type signtures
Marc Busqué
marc at lamarciana.com
Fri Apr 20 18:33:10 UTC 2018
Hi!
I'm using [selda](https://hackage.haskell.org/package/selda) package in
order to deal with database backends.
Selda uses `TypeOperators` language extension, and it introduces `:*:`
type operator constructor which take concrete types like `RowID` or
`Text` . It also has a `Table` type constructor which takes anything
built with `:*:`). On the other hand, `SeldaM` is selda custom monad
transformer with `IO` at the bottom.
I have following helper function which just wraps a call to the SQLite
backend. `dBPath` is just the database file path:
```
withDB :: SeldaM a -> IO a
withDB act = do
path <- dBPath
withSQLite path act
```
I want to wrap selda API in custom functions to be more resilient to
changes. Right now I'm trying to abstract selecting all rows for a given
table (maybe it seems brittle, but it is just a toy project in order to
learn Haskell):
```
list table = withDB $ query (select table)
```
Not adding a type signature to `list` produces following compilation
error:
```
• Non type-variable argument
in the constraint: selda-0.1.12.1:Database.Selda.Column.Columns
(selda-0.1.12.1:Database.Selda.Column.Cols s a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
list :: forall s a.
(selda-0.1.12.1:Database.Selda.Column.Columns
(selda-0.1.12.1:Database.Selda.Column.Cols s a),
selda-0.1.12.1:Database.Selda.Compile.Result
(selda-0.1.12.1:Database.Selda.Column.Cols s a)) =>
Table a
-> IO
[selda-0.1.12.1:Database.Selda.Compile.Res
(selda-0.1.12.1:Database.Selda.Column.Cols s a)]
```
If I try to add what I think would be the correct signature:
```
list :: Table a -> IO [a]
```
The error changes to:
```
• Couldn't match type ‘a’
with ‘selda-0.1.12.1:Database.Selda.Compile.Res
(selda-0.1.12.1:Database.Selda.Column.Cols s0 a)’
‘a’ is a rigid type variable bound by
the type signature for:
list :: forall a. Table a -> IO [a]
at src/Hedger/Category.hs:35:1-25
Expected type: SeldaM [a]
Actual type: selda-0.1.12.1:Database.Selda.Backend.Internal.SeldaT
IO
[selda-0.1.12.1:Database.Selda.Compile.Res
(selda-0.1.12.1:Database.Selda.Column.Cols s0 a)]
• In the second argument of ‘($)’, namely ‘query (select table)’
In the expression: withDB $ query (select table)
In an equation for ‘list’:
list table = withDB $ query (select table)
• Relevant bindings include
table :: Table a (bound at src/Hedger/Category.hs:36:6)
list :: Table a -> IO [a] (bound at src/Hedger/Category.hs:36:1)
|
36 | list table = withDB $ query (select table)
```
However, if I constraint the type signature to act just for a given
table, it compiles without errors:
```
type CategoriesSchema = RowID:*:Text
list :: Table CategoriesSchema -> IO [CategoriesSchema]
```
Why is that it works with concrete types but not with a type variable
that takes the same concrete type in its both placeholders?
Thanks in advance,
Marc Busqué
http://waiting-for-dev.github.io/about/
More information about the Haskell-Cafe
mailing list