Giter Site home page Giter Site logo

rel8's Introduction

Welcome!

Welcome to Rel8! Rel8 is a Haskell library for interacting with PostgreSQL databases, built on top of the fantastic Opaleye library.

The main objectives of Rel8 are:

  • Conciseness: Users using Rel8 should not need to write boiler-plate code. By using expressive types, we can provide sufficient information for the compiler to infer code whenever possible.

  • Inferrable: Despite using a lot of type level magic, Rel8 aims to have excellent and predictable type inference.

  • Familiar: writing Rel8 queries should feel like normal Haskell programming.

Rel8 was presented at ZuriHac 2021. If you want to have a brief overview of what Rel8 is, and a tour of the API - check out the video below:

Rel8 presentation at ZuriHac 2021

For more details, check out the official documentation.

rel8's People

Contributors

abigailalice avatar ashwinmathi avatar bergmark avatar chrisdone-artificial avatar chrismanning avatar dougburke avatar gkaracha avatar gpampara avatar jonathanlorimer avatar kiara-riley avatar marcosh avatar masaeedu avatar ocharles avatar pranaysashank avatar rtaintor avatar shane-circuithub avatar tomjaguarpaw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rel8's Issues

Nesting/unnesting many/catListTable crashes?

Consider the following Rel8 program. It produces SQL which crashes.

Query Error: error: could not identify column "f1" in record data type

Is this known/expected?

The ultimate problem is that .f1, .f2, etc. for accessing fields of ROWs don't really work "through" SELECTs.

*Rel8 Data.Int Prelude> putStr $ showQuery $ do { q1 <- many (many (values [1 , 2 :: Expr Int16])); q2 <- catListTable q1; catListTable q2 }
SELECT
CAST("unnest0_9" AS int2) as "anon"
FROM (SELECT
      UNNEST("unnest0_7") as "unnest0_9",
      *
      FROM (SELECT
            (UNNEST(CASE WHEN ("rebind0_5") IS NULL THEN CAST(ARRAY[] AS record[]) ELSE "result0_4" END)).f1 as "unnest0_7",
            *
            FROM (SELECT *
                  FROM
                  (SELECT
                   0) as "T1"
                  LEFT OUTER JOIN
                  (SELECT
                   TRUE as "rebind0_5",
                   *
                   FROM (SELECT
                         *
                         FROM (SELECT
                               ARRAY_AGG("inner0_4") as "result0_4"
                               FROM (SELECT
                                     ROW(CASE WHEN ("rebind0_3") IS NULL THEN CAST(ARRAY[] AS int2[]) ELSE "result0_2" END) as "inner0_4",
                                     *
                                     FROM (SELECT *
                                           FROM
                                           (SELECT
                                            0) as "T1"
                                           LEFT OUTER JOIN
                                           (SELECT
                                            TRUE as "rebind0_3",
                                            *
                                            FROM (SELECT
                                                  *
                                                  FROM (SELECT
                                                        ARRAY_AGG("inner0_2") as "result0_2"
                                                        FROM (SELECT
                                                              "values0_1" as "inner0_2",
                                                              *
                                                              FROM (SELECT
                                                                    *
                                                                    FROM (SELECT "column1" as "values0_1"
                                                                          FROM
                                                                          (VALUES
                                                                           (CAST(1 AS int2)),
                                                                           (CAST(2 AS int2))) as "V") as "T1") as "T1") as "T1"
                                                        GROUP BY COALESCE(0)) as "T1") as "T1") as "T2"
                                           ON
                                           TRUE) as "T1") as "T1"
                               GROUP BY COALESCE(0)) as "T1") as "T1") as "T2"
                  ON
                  TRUE) as "T1") as "T1") as "T1"

Improve documentation for ordering nulls

How do I order by a nullable column? This doesn't work:

data SomeTable f = SomeTable {
  someColumn :: Column f (Maybe UTCTime)
}

-- ...

someQuery = do
  row <- each someTableSchema
  orderBy (someColumn >$< desc) row

GHC complains:

    • No instance for (DBOrd (Maybe UTCTime))
        arising from a use of ‘desc’
    • In the second argument of ‘(>$<)’, namely ‘desc’
      In the first argument of ‘orderBy’, namely ‘(someColumn >$< desc)’
      In the expression: orderBy (someColumn >$< desc)

I was surprised to discover that there is no instance (DBOrd a) => DBOrd (Maybe a). Is this missing, or is this intentional? Is there a better way to order a nullable field?

Add Nullable and NotNullable type aliases

Writing IsMaybe a ~ 'False is an indirect way of saying NotNullable a. The latter is clearer (there's more intent), and also saves users incurring a DataKinds extension.

My suggestion is:

type NotNullable a = (DBType a, IsMaybe a ~ 'False)
type Nullable a = (DBType a, IsMaybe a ~ 'True)

though maybe pushing that DBType in is a bit too much.

Tree-Like queries don't return empty lists when no joined rows match

TL;DR: I'd like to be able to get an empty list back from a listAgg tree-like query please


I am trying to use tree like queries, which by the way is a killer feature. However, I am running into an issue where no parent rows(post in the cookbook example) are returned when a joined table(tag in the cookbook) returns no matches. I should be on the latest version of rel8 and opaleye.

Since we are using listAgg, I would expect that an empty list is returned with the row when there are no matches in the aggregation. Doubly so when I look at the API and see a nonEmptyAgg right next door that I would expect to give me no parent rows unless 1+ aggregate rows are also returned. However I am getting no parent rows back despite my expectation. Let me know if my expectations are off and we can make this a feature request instead.

I did some investigation and I think I know why the generated query is wrong but I can't figure out the internals well enough to understand why it is generated like that. The culprit is a GROUP BY COALESCE(0) that it seems like opaleye uses often. When this group by is put into a LATERAL it ends up not returning rows where the ARRAY_AGG ends up being null(for example if the WHERE clause doesn't match something). You can see the postgres behavior in these queries that demonstrate the issue:

Fiddle link: https://www.db-fiddle.com/f/snjDmkJGqcmFu45dX4tcAz/7
Queries here for posterity:

create table a 
(
  id text
  );
  
create table b
(
  bid text,
  aid text
  );
  
  insert into a (id) values
  ('1'),
  ('2'),
  ('3');
  
 insert into b (bid, aid) values
 ('x', '1'),
 ('y', '2'),
 ('z', '1');


select * from (select id from a as t1) as t1,
lateral
(select array_agg(aid), array_agg(bid) from
  (select bid, aid from b
	where id = aid) as b1
 group by coalesce(0)
) as b
;

select * from (select id from a as t1) as t1,
lateral
(select array_agg(aid), array_agg(bid) from
  (select bid, aid from b
	where id = aid) as b1
) as b
;

The second query returns all rows like I expect(although it returns null instead of [], which could be fixed with a coalesce) but the first query is close to what rel8 generates.


I also show no difference in listAgg and nonEmptyAgg when used in aggregate. The following use the cookbook schema copy pasted.

listTest :: Query (ListTable Expr (Project Expr))                                                                                                                                                                                                                                                                                                                                            
listTest = aggregate $ do                                                                                                                                                                                                                                                                                                                                                                    
  p <- each projectSchema                                                                                                                                                                                                                                                                                                                                                                    
  pure $ listAgg p                                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                             
nonEmptyTest :: Query (NonEmptyTable Expr (Project Expr))                                                                                                                                                                                                                                                                                                                                    
nonEmptyTest = aggregate $ do                                                                                                                                                                                                                                                                                                                                                                
  p <- each projectSchema                                                                                                                                                                                                                                                                                                                                                                    
  pure $ nonEmptyAgg p
*Bug Rel8> showQuery listTest                                                                                                                                                                                                                                                                                                                                                                
"SELECT                                                                                                                                                                                                                                                                                                                                                                                      
CAST(\"result0_3\" AS int8[]) as \"projectAuthorId\",                                                                                                                                                                                                                                                                                                                                        
CAST(\"result1_3\" AS text[]) as \"projectName\"                                                                                                                                                                                                                                                                                                                                             
FROM (SELECT                                                                                                                                                                                                                                                                                                                                                                                 
      *                                                                                                                                                                                                                                                                                                                                                                                      
      FROM (SELECT                                                                                                                                                                                                                                                                                                                                                                           
            ARRAY_AGG(\"inner0_3\") as \"result0_3\",                                                                                                                                                                                                                                                                                                                                        
            ARRAY_AGG(\"inner1_3\") as \"result1_3\"                                                                                                                                                                                                                                                                                                                                         
            FROM (SELECT                                                                                                                                                                                                                                                                                                                                                                     
                  \"author_id0_1\" as \"inner0_3\",                                                                                                                                                                                                                                                                                                                                          
                  \"name1_1\" as \"inner1_3\",                                                                                                                                                                                                                                                                                                                                               
                  *                                                                                                                                                                                                                                                                                                                                                                          
                  FROM (SELECT                                                                                                                                                                                                                                                                                                                                                               
                        *                                                                                                                                                                                                                                                                                                                                                                    
                        FROM (SELECT                                                                                                                                                                                                                                                                                                                                                         
                              \"author_id\" as \"author_id0_1\",                                                                                                                                                                                                                                                                                                                             
                              \"name\" as \"name1_1\"                                                                                                                                                                                                                                                                                                                                        
                              FROM \"project\" as \"T1\") as \"T1\") as \"T1\") as \"T1\"                                                                                                                                                                                                                                                                                                    
            GROUP BY COALESCE(0)) as \"T1\") as \"T1\""                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                             
*Bug Rel8> showQuery nonEmptyTest                                                                                                                                                                                                                                                                                                                                                            
"SELECT                                                                                                                                                                                                                                                                                                                                                                                      
CAST(\"result0_3\" AS int8[]) as \"projectAuthorId\",                                                                                                                                                                                                                                                                                                                                        
CAST(\"result1_3\" AS text[]) as \"projectName\"                                                                                                                                                                                                                                                                                                                                             
FROM (SELECT                                                                                                                                                                                                                                                                                                                                                                                 
      *                                                                                                                                                                                                                                                                                                                                                                                      
      FROM (SELECT                                                                                                                                                                                                                                                                                                                                                                           
            ARRAY_AGG(\"inner0_3\") as \"result0_3\",                                                                                                                                                                                                                                                                                                                                        
            ARRAY_AGG(\"inner1_3\") as \"result1_3\"                                                                                                                                                                                                                                                                                                                                         
            FROM (SELECT                                                                                                                                                                                                                                                                                                                                                                     
                  \"author_id0_1\" as \"inner0_3\",                                                                                                                                                                                                                                                                                                                                          
                  \"name1_1\" as \"inner1_3\",                                                                                                                                                                                                                                                                                                                                               
                  *                                                                                                                                                                                                                                                                                                                                                                          
                  FROM (SELECT                                                                                                                                                                                                                                                                                                                                                               
                        *                                                                                                                                                                                                                                                                                                                                                                    
                        FROM (SELECT                                                                                                                                                                                                                                                                                                                                                         
                              \"author_id\" as \"author_id0_1\",                                                                                                                                                                                                                                                                                                                             
                              \"name\" as \"name1_1\"                                                                                                                                                                                                                                                                                                                                        
                              FROM \"project\" as \"T1\") as \"T1\") as \"T1\") as \"T1\"                                                                                                                                                                                                                                                                                                    
            GROUP BY COALESCE(0)) as \"T1\") as \"T1\""                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                             
*Bug Rel8>                

I would expect that there would be some sort of difference in these queries but I do admit that it is possible they change when used in the whole tree query.

Property tests are flaky when testing equality (coverage condition can fail)

Full log below:

setupCompilerEnvironmentPhase
Build with /nix/store/y0bj63wn081cgzrsqafda6g1kp20cnc6-ghc-8.10.4.
unpacking sources
unpacking source archive /nix/store/ra902w71yy8c4hf978bpfs3lfp7y0vr2-rel8-1.0.0.1.tar.gz
source root is rel8-1.0.0.1
setting SOURCE_DATE_EPOCH to timestamp 1000000000 of file rel8-1.0.0.1/tests/Main.hs
patching sources
compileBuildDriverPhase
setupCompileFlags: -package-db=/build/setup-package.conf.d -j2 +RTS -A64M -RTS -threaded -rtsopts
[1 of 1] Compiling Main             ( /nix/store/4mdp8nhyfddh7bllbi7xszz7k9955n79-Setup.hs, /build/Main.o )
Linking Setup ...
updateAutotoolsGnuConfigScriptsPhase
configuring
configureFlags: --verbose --prefix=/nix/store/f4zdsnzvaxdvf6mhv5jqvcs55vkg0slp-rel8-1.0.0.1 --libdir=$prefix/lib/$compiler --libsubdir=$abi/$libname --docdir=/nix/store/bn7g88jsmlj20vxvw9cizq1ha67aqsg2-rel8-1.0.0.1-doc/share/doc/rel8-1.0.0.1 --with-gcc=gcc --package-db=/build/package.conf.d --ghc-options=-j2 +RTS -A64M -RTS --disable-split-objs --disable-library-profiling --disable-profiling --enable-shared --disable-coverage --enable-static --disable-executable-dynamic --enable-tests --disable-benchmarks --enable-library-vanilla --disable-library-for-ghci --ghc-option=-split-sections --extra-lib-dirs=/nix/store/4wsq4c9v3hjlmbiaq8d8r1al7pm27jib-ncurses-6.2/lib --extra-lib-dirs=/nix/store/5nfzqvmi06kwrlv96cgzw1hpchb732pb-libffi-3.3/lib --extra-lib-dirs=/nix/store/xwcg8glanp8j60867akkjhjgs8mkcgqj-gmp-6.2.1/lib
Using Parsec parser
Configuring rel8-1.0.0.1...
Dependency aeson -any: using aeson-1.5.6.0
Dependency base >=4.14 && <4.16: using base-4.14.1.0
Dependency bytestring -any: using bytestring-0.10.12.0
Dependency case-insensitive -any: using case-insensitive-1.2.1.0
Dependency contravariant -any: using contravariant-1.5.3
Dependency hasql >=1.4.5.1 && <1.5: using hasql-1.4.5.1
Dependency opaleye >=0.7.1.0 && <0.8: using opaleye-0.7.1.0
Dependency profunctors -any: using profunctors-5.6.2
Dependency scientific -any: using scientific-0.3.7.0
Dependency semialign -any: using semialign-1.1.0.1
Dependency semigroupoids -any: using semigroupoids-5.3.5
Dependency text -any: using text-1.2.4.1
Dependency these -any: using these-1.1.1.1
Dependency time -any: using time-1.9.3
Dependency transformers -any: using transformers-0.5.6.2
Dependency uuid -any: using uuid-1.3.15
Dependency base -any: using base-4.14.1.0
Dependency bytestring -any: using bytestring-0.10.12.0
Dependency case-insensitive -any: using case-insensitive-1.2.1.0
Dependency containers -any: using containers-0.6.2.1
Dependency hasql -any: using hasql-1.4.5.1
Dependency hedgehog >=1.0.2 && <1.1: using hedgehog-1.0.5
Dependency lifted-base >=0.2.3.12 && <0.3: using lifted-base-0.2.3.12
Dependency monad-control >=1.0.2.3 && <1.1: using monad-control-1.0.2.3
Dependency rel8 -any: using rel8-1.0.0.1
Dependency scientific -any: using scientific-0.3.7.0
Dependency tasty -any: using tasty-1.4.1
Dependency tasty-hedgehog -any: using tasty-hedgehog-1.1.0.0
Dependency text -any: using text-1.2.4.1
Dependency time -any: using time-1.9.3
Dependency tmp-postgres >=1.34.1.0 && <1.35: using tmp-postgres-1.34.1.0
Dependency uuid -any: using uuid-1.3.15
Source component graph:
    component lib
    component test:tests dependency lib
Configured component graph:
    component rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D
        include aeson-1.5.6.0-7VtAbFhiMD86nhm14AnXd3
        include base-4.14.1.0
        include bytestring-0.10.12.0
        include case-insensitive-1.2.1.0-8WQTGShGTbbJS2KfrTMT63
        include contravariant-1.5.3-Ac4TAzGGDBLeGMWs4L1e
        include hasql-1.4.5.1-4f0m8EaztekGWTy2VYEv1O
        include opaleye-0.7.1.0-BONBtxG16GgLGGzfC1u3ry
        include profunctors-5.6.2-37YClCtYaGDB7IsRqTu42n
        include scientific-0.3.7.0-JBQHhnyOQiWDaq3boYBVJG
        include semialign-1.1.0.1-U65jveep7G9WO9skMu0RU
        include semigroupoids-5.3.5-DnSXpnxVY0aA89Kf9RZXSs
        include text-1.2.4.1
        include these-1.1.1.1-F1x7zOn2rPpLWE7lng5VFt
        include time-1.9.3
        include transformers-0.5.6.2
        include uuid-1.3.15-D6N9MBFy2bh1rE8cdbKa8J
    component rel8-1.0.0.1-AuiUywqwJ8JDZy0zTBv2z-tests
        include base-4.14.1.0
        include bytestring-0.10.12.0
        include case-insensitive-1.2.1.0-8WQTGShGTbbJS2KfrTMT63
        include containers-0.6.2.1
        include hasql-1.4.5.1-4f0m8EaztekGWTy2VYEv1O
        include hedgehog-1.0.5-EY93k4yvtpWCmTGnbBrkno
        include lifted-base-0.2.3.12-EpB7rUKMW3R5VIFx4SuI6V
        include monad-control-1.0.2.3-80auGb0l24oD26SNu1t5Lm
        include rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D
        include scientific-0.3.7.0-JBQHhnyOQiWDaq3boYBVJG
        include tasty-1.4.1-FtpRBlVwPMFDS4ISbZig60
        include tasty-hedgehog-1.1.0.0-DUTAKfwTdRGEGK7loz1KZh
        include text-1.2.4.1
        include time-1.9.3
        include tmp-postgres-1.34.1.0-7fRyztdmEK28gpvkCea2lN
        include uuid-1.3.15-D6N9MBFy2bh1rE8cdbKa8J
Linked component graph:
    unit rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D
        include aeson-1.5.6.0-7VtAbFhiMD86nhm14AnXd3
        include base-4.14.1.0
        include bytestring-0.10.12.0
        include case-insensitive-1.2.1.0-8WQTGShGTbbJS2KfrTMT63
        include contravariant-1.5.3-Ac4TAzGGDBLeGMWs4L1e
        include hasql-1.4.5.1-4f0m8EaztekGWTy2VYEv1O
        include opaleye-0.7.1.0-BONBtxG16GgLGGzfC1u3ry
        include profunctors-5.6.2-37YClCtYaGDB7IsRqTu42n
        include scientific-0.3.7.0-JBQHhnyOQiWDaq3boYBVJG
        include semialign-1.1.0.1-U65jveep7G9WO9skMu0RU
        include semigroupoids-5.3.5-DnSXpnxVY0aA89Kf9RZXSs
        include text-1.2.4.1
        include these-1.1.1.1-F1x7zOn2rPpLWE7lng5VFt
        include time-1.9.3
        include transformers-0.5.6.2
        include uuid-1.3.15-D6N9MBFy2bh1rE8cdbKa8J
        Rel8=rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D:Rel8,Rel8.Expr.Num=rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D:Rel8.Expr.Num,Rel8.Expr.Text=rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D:Rel8.Expr.Text,Rel8.Expr.Time=rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D:Rel8.Expr.Time
    unit rel8-1.0.0.1-AuiUywqwJ8JDZy0zTBv2z-tests
        include base-4.14.1.0
        include bytestring-0.10.12.0
        include case-insensitive-1.2.1.0-8WQTGShGTbbJS2KfrTMT63
        include containers-0.6.2.1
        include hasql-1.4.5.1-4f0m8EaztekGWTy2VYEv1O
        include hedgehog-1.0.5-EY93k4yvtpWCmTGnbBrkno
        include lifted-base-0.2.3.12-EpB7rUKMW3R5VIFx4SuI6V
        include monad-control-1.0.2.3-80auGb0l24oD26SNu1t5Lm
        include rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D
        include scientific-0.3.7.0-JBQHhnyOQiWDaq3boYBVJG
        include tasty-1.4.1-FtpRBlVwPMFDS4ISbZig60
        include tasty-hedgehog-1.1.0.0-DUTAKfwTdRGEGK7loz1KZh
        include text-1.2.4.1
        include time-1.9.3
        include tmp-postgres-1.34.1.0-7fRyztdmEK28gpvkCea2lN
        include uuid-1.3.15-D6N9MBFy2bh1rE8cdbKa8J
Ready component graph:
    definite rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D
        depends aeson-1.5.6.0-7VtAbFhiMD86nhm14AnXd3
        depends base-4.14.1.0
        depends bytestring-0.10.12.0
        depends case-insensitive-1.2.1.0-8WQTGShGTbbJS2KfrTMT63
        depends contravariant-1.5.3-Ac4TAzGGDBLeGMWs4L1e
        depends hasql-1.4.5.1-4f0m8EaztekGWTy2VYEv1O
        depends opaleye-0.7.1.0-BONBtxG16GgLGGzfC1u3ry
        depends profunctors-5.6.2-37YClCtYaGDB7IsRqTu42n
        depends scientific-0.3.7.0-JBQHhnyOQiWDaq3boYBVJG
        depends semialign-1.1.0.1-U65jveep7G9WO9skMu0RU
        depends semigroupoids-5.3.5-DnSXpnxVY0aA89Kf9RZXSs
        depends text-1.2.4.1
        depends these-1.1.1.1-F1x7zOn2rPpLWE7lng5VFt
        depends time-1.9.3
        depends transformers-0.5.6.2
        depends uuid-1.3.15-D6N9MBFy2bh1rE8cdbKa8J
    definite rel8-1.0.0.1-AuiUywqwJ8JDZy0zTBv2z-tests
        depends base-4.14.1.0
        depends bytestring-0.10.12.0
        depends case-insensitive-1.2.1.0-8WQTGShGTbbJS2KfrTMT63
        depends containers-0.6.2.1
        depends hasql-1.4.5.1-4f0m8EaztekGWTy2VYEv1O
        depends hedgehog-1.0.5-EY93k4yvtpWCmTGnbBrkno
        depends lifted-base-0.2.3.12-EpB7rUKMW3R5VIFx4SuI6V
        depends monad-control-1.0.2.3-80auGb0l24oD26SNu1t5Lm
        depends rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D
        depends scientific-0.3.7.0-JBQHhnyOQiWDaq3boYBVJG
        depends tasty-1.4.1-FtpRBlVwPMFDS4ISbZig60
        depends tasty-hedgehog-1.1.0.0-DUTAKfwTdRGEGK7loz1KZh
        depends text-1.2.4.1
        depends time-1.9.3
        depends tmp-postgres-1.34.1.0-7fRyztdmEK28gpvkCea2lN
        depends uuid-1.3.15-D6N9MBFy2bh1rE8cdbKa8J
Using Cabal-3.2.1.0 compiled by ghc-8.10
Using compiler: ghc-8.10.4
Using install prefix: /nix/store/f4zdsnzvaxdvf6mhv5jqvcs55vkg0slp-rel8-1.0.0.1
Executables installed in:
/nix/store/f4zdsnzvaxdvf6mhv5jqvcs55vkg0slp-rel8-1.0.0.1/bin
Libraries installed in:
/nix/store/f4zdsnzvaxdvf6mhv5jqvcs55vkg0slp-rel8-1.0.0.1/lib/ghc-8.10.4/aarch64-linux-ghc-8.10.4/rel8-1.0.0.1-HkBvFtwIUqm2kNCC483P8D
Dynamic Libraries installed in:
/nix/store/f4zdsnzvaxdvf6mhv5jqvcs55vkg0slp-rel8-1.0.0.1/lib/ghc-8.10.4/aarch64-linux-ghc-8.10.4
Private executables installed in:
/nix/store/f4zdsnzvaxdvf6mhv5jqvcs55vkg0slp-rel8-1.0.0.1/libexec/aarch64-linux-ghc-8.10.4/rel8-1.0.0.1
Data files installed in:
/nix/store/f4zdsnzvaxdvf6mhv5jqvcs55vkg0slp-rel8-1.0.0.1/share/aarch64-linux-ghc-8.10.4/rel8-1.0.0.1
Documentation installed in:
/nix/store/bn7g88jsmlj20vxvw9cizq1ha67aqsg2-rel8-1.0.0.1-doc/share/doc/rel8-1.0.0.1
Configuration files installed in:
/nix/store/f4zdsnzvaxdvf6mhv5jqvcs55vkg0slp-rel8-1.0.0.1/etc
No alex found
Using ar found on system at:
/nix/store/hv8s4ni4n89h6n27gwq31bb3lbgnssva-binutils-2.35.1/bin/ar
No c2hs found
No cpphs found
No doctest found
Using gcc version 9.3.0 given by user at:
/nix/store/vv9ij1wd45vckp9bm1xp776zb51h4wcq-gcc-wrapper-9.3.0/bin/gcc
Using ghc version 8.10.4 found on system at:
/nix/store/y0bj63wn081cgzrsqafda6g1kp20cnc6-ghc-8.10.4/bin/ghc
Using ghc-pkg version 8.10.4 found on system at:
/nix/store/y0bj63wn081cgzrsqafda6g1kp20cnc6-ghc-8.10.4/bin/ghc-pkg
No ghcjs found
No ghcjs-pkg found
No greencard found
Using haddock version 2.24.0 found on system at:
/nix/store/y0bj63wn081cgzrsqafda6g1kp20cnc6-ghc-8.10.4/bin/haddock
No happy found
Using haskell-suite found on system at: haskell-suite-dummy-location
Using haskell-suite-pkg found on system at: haskell-suite-pkg-dummy-location
No hmake found
Using hpc version 0.68 found on system at:
/nix/store/y0bj63wn081cgzrsqafda6g1kp20cnc6-ghc-8.10.4/bin/hpc
Using hsc2hs version 0.68.7 found on system at:
/nix/store/y0bj63wn081cgzrsqafda6g1kp20cnc6-ghc-8.10.4/bin/hsc2hs
Using hscolour version 1.24 found on system at:
/nix/store/b96psvb6ndwkfz0349l2587v8lqc6czl-hscolour-1.24.4/bin/HsColour
No jhc found
Using ld found on system at:
/nix/store/787y6bs71f492wyhzjdzqbsw3l1h143i-binutils-wrapper-2.35.1/bin/ld.gold
No pkg-config found
Using runghc version 8.10.4 found on system at:
/nix/store/y0bj63wn081cgzrsqafda6g1kp20cnc6-ghc-8.10.4/bin/runghc
Using strip version 2.35 found on system at:
/nix/store/hv8s4ni4n89h6n27gwq31bb3lbgnssva-binutils-2.35.1/bin/strip
Using tar found on system at:
/nix/store/nipr8axxz60xm6kv2ckmfg613nmcf7mm-gnutar-1.34/bin/tar
No uhc found
building
Preprocessing library for rel8-1.0.0.1..
Building library for rel8-1.0.0.1..
[  1 of 129] Compiling Rel8.Expr[boot]  ( src/Rel8/Expr.hs-boot, dist/build/Rel8/Expr.o-boot, dist/build/Rel8/Expr.dyn_o )
[  2 of 129] Compiling Rel8.FCF         ( src/Rel8/FCF.hs, dist/build/Rel8/FCF.o, dist/build/Rel8/FCF.dyn_o )
[  3 of 129] Compiling Rel8.Generic.Map ( src/Rel8/Generic/Map.hs, dist/build/Rel8/Generic/Map.o, dist/build/Rel8/Generic/Map.dyn_o )
[  4 of 129] Compiling Rel8.Generic.Record ( src/Rel8/Generic/Record.hs, dist/build/Rel8/Generic/Record.o, dist/build/Rel8/Generic/Record.dyn_o )
[  5 of 129] Compiling Rel8.Generic.Reify ( src/Rel8/Generic/Reify.hs, dist/build/Rel8/Generic/Reify.o, dist/build/Rel8/Generic/Reify.dyn_o )
[  6 of 129] Compiling Rel8.Kind.Algebra ( src/Rel8/Kind/Algebra.hs, dist/build/Rel8/Kind/Algebra.o, dist/build/Rel8/Kind/Algebra.dyn_o )
[  7 of 129] Compiling Rel8.Kind.Labels ( src/Rel8/Kind/Labels.hs, dist/build/Rel8/Kind/Labels.o, dist/build/Rel8/Kind/Labels.dyn_o )
[  8 of 129] Compiling Rel8.Order       ( src/Rel8/Order.hs, dist/build/Rel8/Order.o, dist/build/Rel8/Order.dyn_o )
[  9 of 129] Compiling Rel8.Query[boot] ( src/Rel8/Query.hs-boot, dist/build/Rel8/Query.o-boot, dist/build/Rel8/Query.dyn_o )
[ 10 of 129] Compiling Rel8.Query.Opaleye ( src/Rel8/Query/Opaleye.hs, dist/build/Rel8/Query/Opaleye.o, dist/build/Rel8/Query/Opaleye.dyn_o )
[ 11 of 129] Compiling Rel8.Schema.Dict ( src/Rel8/Schema/Dict.hs, dist/build/Rel8/Schema/Dict.o, dist/build/Rel8/Schema/Dict.dyn_o )
[ 12 of 129] Compiling Rel8.Schema.Null ( src/Rel8/Schema/Null.hs, dist/build/Rel8/Schema/Null.o, dist/build/Rel8/Schema/Null.dyn_o )
[ 13 of 129] Compiling Rel8.Schema.Table ( src/Rel8/Schema/Table.hs, dist/build/Rel8/Schema/Table.o, dist/build/Rel8/Schema/Table.dyn_o )
[ 14 of 129] Compiling Rel8.Type.Information ( src/Rel8/Type/Information.hs, dist/build/Rel8/Type/Information.o, dist/build/Rel8/Type/Information.dyn_o )
[ 15 of 129] Compiling Rel8.Type.Array  ( src/Rel8/Type/Array.hs, dist/build/Rel8/Type/Array.o, dist/build/Rel8/Type/Array.dyn_o )
[ 16 of 129] Compiling Rel8.Type        ( src/Rel8/Type.hs, dist/build/Rel8/Type.o, dist/build/Rel8/Type.dyn_o )

src/Rel8/Type.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘GHC.Real.$wrealToFrac’
      when specialising ‘realToFrac’
    Probable fix: add INLINABLE pragma on ‘GHC.Real.$wrealToFrac’
[ 17 of 129] Compiling Rel8.Type.Eq     ( src/Rel8/Type/Eq.hs, dist/build/Rel8/Type/Eq.o, dist/build/Rel8/Type/Eq.dyn_o )
[ 18 of 129] Compiling Rel8.Schema.Spec ( src/Rel8/Schema/Spec.hs, dist/build/Rel8/Schema/Spec.o, dist/build/Rel8/Schema/Spec.dyn_o )
[ 19 of 129] Compiling Rel8.Schema.Spec.ConstrainDBType ( src/Rel8/Schema/Spec/ConstrainDBType.hs, dist/build/Rel8/Schema/Spec/ConstrainDBType.o, dist/build/Rel8/Schema/Spec/ConstrainDBType.dyn_o )
[ 20 of 129] Compiling Rel8.Schema.Kind ( src/Rel8/Schema/Kind.hs, dist/build/Rel8/Schema/Kind.o, dist/build/Rel8/Schema/Kind.dyn_o )
[ 21 of 129] Compiling Rel8.Schema.HTable.Product ( src/Rel8/Schema/HTable/Product.hs, dist/build/Rel8/Schema/HTable/Product.o, dist/build/Rel8/Schema/HTable/Product.dyn_o )
[ 22 of 129] Compiling Rel8.Schema.Context ( src/Rel8/Schema/Context.hs, dist/build/Rel8/Schema/Context.o, dist/build/Rel8/Schema/Context.dyn_o )
[ 23 of 129] Compiling Rel8.Schema.HTable ( src/Rel8/Schema/HTable.hs, dist/build/Rel8/Schema/HTable.o, dist/build/Rel8/Schema/HTable.dyn_o )
[ 24 of 129] Compiling Rel8.Schema.HTable.MapTable ( src/Rel8/Schema/HTable/MapTable.hs, dist/build/Rel8/Schema/HTable/MapTable.o, dist/build/Rel8/Schema/HTable/MapTable.dyn_o )
[ 25 of 129] Compiling Rel8.Schema.HTable.Nullify ( src/Rel8/Schema/HTable/Nullify.hs, dist/build/Rel8/Schema/HTable/Nullify.o, dist/build/Rel8/Schema/HTable/Nullify.dyn_o )
[ 26 of 129] Compiling Rel8.Schema.HTable.Label ( src/Rel8/Schema/HTable/Label.hs, dist/build/Rel8/Schema/HTable/Label.o, dist/build/Rel8/Schema/HTable/Label.dyn_o )
[ 27 of 129] Compiling Rel8.Schema.HTable.Identity ( src/Rel8/Schema/HTable/Identity.hs, dist/build/Rel8/Schema/HTable/Identity.o, dist/build/Rel8/Schema/HTable/Identity.dyn_o )
[ 28 of 129] Compiling Rel8.Schema.Result ( src/Rel8/Schema/Result.hs, dist/build/Rel8/Schema/Result.o, dist/build/Rel8/Schema/Result.dyn_o )
[ 29 of 129] Compiling Rel8.Schema.Context.Label ( src/Rel8/Schema/Context/Label.hs, dist/build/Rel8/Schema/Context/Label.o, dist/build/Rel8/Schema/Context/Label.dyn_o )
[ 30 of 129] Compiling Rel8.Schema.Reify ( src/Rel8/Schema/Reify.hs, dist/build/Rel8/Schema/Reify.o, dist/build/Rel8/Schema/Reify.dyn_o )
[ 31 of 129] Compiling Rel8.Generic.Table.Record ( src/Rel8/Generic/Table/Record.hs, dist/build/Rel8/Generic/Table/Record.o, dist/build/Rel8/Generic/Table/Record.dyn_o )
[ 32 of 129] Compiling Rel8.Generic.Construction.Record ( src/Rel8/Generic/Construction/Record.hs, dist/build/Rel8/Generic/Construction/Record.o, dist/build/Rel8/Generic/Construction/Record.dyn_o )
[ 33 of 129] Compiling Rel8.Schema.HTable.Vectorize ( src/Rel8/Schema/HTable/Vectorize.hs, dist/build/Rel8/Schema/HTable/Vectorize.o, dist/build/Rel8/Schema/HTable/Vectorize.dyn_o )
[ 34 of 129] Compiling Rel8.Schema.HTable.NonEmpty ( src/Rel8/Schema/HTable/NonEmpty.hs, dist/build/Rel8/Schema/HTable/NonEmpty.o, dist/build/Rel8/Schema/HTable/NonEmpty.dyn_o )
[ 35 of 129] Compiling Rel8.Schema.HTable.List ( src/Rel8/Schema/HTable/List.hs, dist/build/Rel8/Schema/HTable/List.o, dist/build/Rel8/Schema/HTable/List.dyn_o )
[ 36 of 129] Compiling Rel8.Expr.Opaleye ( src/Rel8/Expr/Opaleye.hs, dist/build/Rel8/Expr/Opaleye.o, dist/build/Rel8/Expr/Opaleye.dyn_o )
[ 37 of 129] Compiling Rel8.Expr.Serialize ( src/Rel8/Expr/Serialize.hs, dist/build/Rel8/Expr/Serialize.o, dist/build/Rel8/Expr/Serialize.dyn_o )
[ 38 of 129] Compiling Rel8.Expr.Function ( src/Rel8/Expr/Function.hs, dist/build/Rel8/Expr/Function.o, dist/build/Rel8/Expr/Function.dyn_o )
[ 39 of 129] Compiling Rel8.Expr.Bool   ( src/Rel8/Expr/Bool.hs, dist/build/Rel8/Expr/Bool.o, dist/build/Rel8/Expr/Bool.dyn_o )
[ 40 of 129] Compiling Rel8.Expr.Null   ( src/Rel8/Expr/Null.hs, dist/build/Rel8/Expr/Null.o, dist/build/Rel8/Expr/Null.dyn_o )
[ 41 of 129] Compiling Rel8.Expr.Eq     ( src/Rel8/Expr/Eq.hs, dist/build/Rel8/Expr/Eq.o, dist/build/Rel8/Expr/Eq.dyn_o )
[ 42 of 129] Compiling Rel8.Expr.Array  ( src/Rel8/Expr/Array.hs, dist/build/Rel8/Expr/Array.o, dist/build/Rel8/Expr/Array.dyn_o )
[ 43 of 129] Compiling Rel8.Type.JSONBEncoded ( src/Rel8/Type/JSONBEncoded.hs, dist/build/Rel8/Type/JSONBEncoded.o, dist/build/Rel8/Type/JSONBEncoded.dyn_o )
[ 44 of 129] Compiling Rel8.Type.JSONEncoded ( src/Rel8/Type/JSONEncoded.hs, dist/build/Rel8/Type/JSONEncoded.o, dist/build/Rel8/Type/JSONEncoded.dyn_o )
[ 45 of 129] Compiling Rel8.Type.Num    ( src/Rel8/Type/Num.hs, dist/build/Rel8/Type/Num.o, dist/build/Rel8/Type/Num.dyn_o )
[ 46 of 129] Compiling Rel8.Type.Ord    ( src/Rel8/Type/Ord.hs, dist/build/Rel8/Type/Ord.o, dist/build/Rel8/Type/Ord.dyn_o )
[ 47 of 129] Compiling Rel8.Type.Enum   ( src/Rel8/Type/Enum.hs, dist/build/Rel8/Type/Enum.o, dist/build/Rel8/Type/Enum.dyn_o )
[ 48 of 129] Compiling Rel8.Type.ReadShow ( src/Rel8/Type/ReadShow.hs, dist/build/Rel8/Type/ReadShow.o, dist/build/Rel8/Type/ReadShow.dyn_o )
[ 49 of 129] Compiling Rel8.Type.Semigroup ( src/Rel8/Type/Semigroup.hs, dist/build/Rel8/Type/Semigroup.o, dist/build/Rel8/Type/Semigroup.dyn_o )
[ 50 of 129] Compiling Rel8.Type.Monoid ( src/Rel8/Type/Monoid.hs, dist/build/Rel8/Type/Monoid.o, dist/build/Rel8/Type/Monoid.dyn_o )
[ 51 of 129] Compiling Rel8.Type.String ( src/Rel8/Type/String.hs, dist/build/Rel8/Type/String.o, dist/build/Rel8/Type/String.dyn_o )
[ 52 of 129] Compiling Rel8.Type.Sum    ( src/Rel8/Type/Sum.hs, dist/build/Rel8/Type/Sum.o, dist/build/Rel8/Type/Sum.dyn_o )
[ 53 of 129] Compiling Rel8.Type.Tag    ( src/Rel8/Type/Tag.hs, dist/build/Rel8/Type/Tag.o, dist/build/Rel8/Type/Tag.dyn_o )

src/Rel8/Type/Tag.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Data.Semigroup.$w$csconcat1’
      when specialising ‘Data.Semigroup.$fSemigroupMin_$csconcat’
    Probable fix: add INLINABLE pragma on ‘Data.Semigroup.$w$csconcat1’
[ 54 of 129] Compiling Rel8.Schema.HTable.These ( src/Rel8/Schema/HTable/These.hs, dist/build/Rel8/Schema/HTable/These.o, dist/build/Rel8/Schema/HTable/These.dyn_o )
[ 55 of 129] Compiling Rel8.Schema.HTable.Maybe ( src/Rel8/Schema/HTable/Maybe.hs, dist/build/Rel8/Schema/HTable/Maybe.o, dist/build/Rel8/Schema/HTable/Maybe.dyn_o )
[ 56 of 129] Compiling Rel8.Schema.HTable.Either ( src/Rel8/Schema/HTable/Either.hs, dist/build/Rel8/Schema/HTable/Either.o, dist/build/Rel8/Schema/HTable/Either.dyn_o )
[ 57 of 129] Compiling Rel8.Generic.Table.ADT ( src/Rel8/Generic/Table/ADT.hs, dist/build/Rel8/Generic/Table/ADT.o, dist/build/Rel8/Generic/Table/ADT.dyn_o )
[ 58 of 129] Compiling Rel8.Generic.Table ( src/Rel8/Generic/Table.hs, dist/build/Rel8/Generic/Table.o, dist/build/Rel8/Generic/Table.dyn_o )
[ 59 of 129] Compiling Rel8.Table       ( src/Rel8/Table.hs, dist/build/Rel8/Table.o, dist/build/Rel8/Table.dyn_o )
[ 60 of 129] Compiling Rel8.Table.Recontextualize ( src/Rel8/Table/Recontextualize.hs, dist/build/Rel8/Table/Recontextualize.o, dist/build/Rel8/Table/Recontextualize.dyn_o )
[ 61 of 129] Compiling Rel8.Expr        ( src/Rel8/Expr.hs, dist/build/Rel8/Expr.o, dist/build/Rel8/Expr.dyn_o )

src/Rel8/Expr.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘GHC.Real.$wrealToFrac’
      when specialising ‘realToFrac’
    Probable fix: add INLINABLE pragma on ‘GHC.Real.$wrealToFrac’
[ 62 of 129] Compiling Rel8.Table.Undefined ( src/Rel8/Table/Undefined.hs, dist/build/Rel8/Table/Undefined.o, dist/build/Rel8/Table/Undefined.dyn_o )
[ 63 of 129] Compiling Rel8.Table.Serialize ( src/Rel8/Table/Serialize.hs, dist/build/Rel8/Table/Serialize.o, dist/build/Rel8/Table/Serialize.dyn_o )
[ 64 of 129] Compiling Rel8.Table.Eq    ( src/Rel8/Table/Eq.hs, dist/build/Rel8/Table/Eq.o, dist/build/Rel8/Table/Eq.dyn_o )
[ 65 of 129] Compiling Rel8.Table.Bool  ( src/Rel8/Table/Bool.hs, dist/build/Rel8/Table/Bool.o, dist/build/Rel8/Table/Bool.dyn_o )
[ 66 of 129] Compiling Rel8.Table.Alternative ( src/Rel8/Table/Alternative.hs, dist/build/Rel8/Table/Alternative.o, dist/build/Rel8/Table/Alternative.dyn_o )
[ 67 of 129] Compiling Rel8.Schema.Name ( src/Rel8/Schema/Name.hs, dist/build/Rel8/Schema/Name.o, dist/build/Rel8/Schema/Name.dyn_o )
[ 68 of 129] Compiling Rel8.Table.Name  ( src/Rel8/Table/Name.hs, dist/build/Rel8/Table/Name.o, dist/build/Rel8/Table/Name.dyn_o )
[ 69 of 129] Compiling Rel8.Statement.Returning ( src/Rel8/Statement/Returning.hs, dist/build/Rel8/Statement/Returning.o, dist/build/Rel8/Statement/Returning.dyn_o )
[ 70 of 129] Compiling Rel8.Expr.Time   ( src/Rel8/Expr/Time.hs, dist/build/Rel8/Expr/Time.o, dist/build/Rel8/Expr/Time.dyn_o )
[ 71 of 129] Compiling Rel8.Expr.Text   ( src/Rel8/Expr/Text.hs, dist/build/Rel8/Expr/Text.o, dist/build/Rel8/Expr/Text.dyn_o )
[ 72 of 129] Compiling Rel8.Expr.Sequence ( src/Rel8/Expr/Sequence.hs, dist/build/Rel8/Expr/Sequence.o, dist/build/Rel8/Expr/Sequence.dyn_o )
[ 73 of 129] Compiling Rel8.Expr.Order  ( src/Rel8/Expr/Order.hs, dist/build/Rel8/Expr/Order.o, dist/build/Rel8/Expr/Order.dyn_o )
[ 74 of 129] Compiling Rel8.Expr.Ord    ( src/Rel8/Expr/Ord.hs, dist/build/Rel8/Expr/Ord.o, dist/build/Rel8/Expr/Ord.dyn_o )
[ 75 of 129] Compiling Rel8.Table.Ord   ( src/Rel8/Table/Ord.hs, dist/build/Rel8/Table/Ord.o, dist/build/Rel8/Table/Ord.dyn_o )
[ 76 of 129] Compiling Rel8.Table.Order ( src/Rel8/Table/Order.hs, dist/build/Rel8/Table/Order.o, dist/build/Rel8/Table/Order.dyn_o )
[ 77 of 129] Compiling Rel8.Expr.Num    ( src/Rel8/Expr/Num.hs, dist/build/Rel8/Expr/Num.o, dist/build/Rel8/Expr/Num.dyn_o )
[ 78 of 129] Compiling Rel8.Aggregate   ( src/Rel8/Aggregate.hs, dist/build/Rel8/Aggregate.o, dist/build/Rel8/Aggregate.dyn_o )
[ 79 of 129] Compiling Rel8.Table.Tag   ( src/Rel8/Table/Tag.hs, dist/build/Rel8/Table/Tag.o, dist/build/Rel8/Table/Tag.dyn_o )
[ 80 of 129] Compiling Rel8.Table.Opaleye ( src/Rel8/Table/Opaleye.hs, dist/build/Rel8/Table/Opaleye.o, dist/build/Rel8/Table/Opaleye.dyn_o )
[ 81 of 129] Compiling Rel8.Statement.Update ( src/Rel8/Statement/Update.hs, dist/build/Rel8/Statement/Update.o, dist/build/Rel8/Statement/Update.dyn_o )
[ 82 of 129] Compiling Rel8.Statement.Insert ( src/Rel8/Statement/Insert.hs, dist/build/Rel8/Statement/Insert.o, dist/build/Rel8/Statement/Insert.dyn_o )
[ 83 of 129] Compiling Rel8.Statement.Delete ( src/Rel8/Statement/Delete.hs, dist/build/Rel8/Statement/Delete.o, dist/build/Rel8/Statement/Delete.dyn_o )
[ 84 of 129] Compiling Rel8.Query.Values ( src/Rel8/Query/Values.hs, dist/build/Rel8/Query/Values.o, dist/build/Rel8/Query/Values.dyn_o )
[ 85 of 129] Compiling Rel8.Query.Set   ( src/Rel8/Query/Set.hs, dist/build/Rel8/Query/Set.o, dist/build/Rel8/Query/Set.dyn_o )
[ 86 of 129] Compiling Rel8.Query       ( src/Rel8/Query.hs, dist/build/Rel8/Query.o, dist/build/Rel8/Query.dyn_o )
[ 87 of 129] Compiling Rel8.Query.Order ( src/Rel8/Query/Order.hs, dist/build/Rel8/Query/Order.o, dist/build/Rel8/Query/Order.dyn_o )
[ 88 of 129] Compiling Rel8.Query.Limit ( src/Rel8/Query/Limit.hs, dist/build/Rel8/Query/Limit.o, dist/build/Rel8/Query/Limit.dyn_o )
[ 89 of 129] Compiling Rel8.Query.Filter ( src/Rel8/Query/Filter.hs, dist/build/Rel8/Query/Filter.o, dist/build/Rel8/Query/Filter.dyn_o )
[ 90 of 129] Compiling Rel8.Query.Null  ( src/Rel8/Query/Null.hs, dist/build/Rel8/Query/Null.o, dist/build/Rel8/Query/Null.dyn_o )
[ 91 of 129] Compiling Rel8.Query.SQL   ( src/Rel8/Query/SQL.hs, dist/build/Rel8/Query/SQL.o, dist/build/Rel8/Query/SQL.dyn_o )
[ 92 of 129] Compiling Rel8.Statement.View ( src/Rel8/Statement/View.hs, dist/build/Rel8/Statement/View.o, dist/build/Rel8/Statement/View.dyn_o )
[ 93 of 129] Compiling Rel8.Statement.Select ( src/Rel8/Statement/Select.hs, dist/build/Rel8/Statement/Select.o, dist/build/Rel8/Statement/Select.dyn_o )
[ 94 of 129] Compiling Rel8.Query.Evaluate ( src/Rel8/Query/Evaluate.hs, dist/build/Rel8/Query/Evaluate.o, dist/build/Rel8/Query/Evaluate.dyn_o )

src/Rel8/Query/Evaluate.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Control.Monad.Trans.State.Lazy.$w$cliftA2’
      when specialising ‘Control.Monad.Trans.State.Lazy.$fApplicativeStateT2’
      when specialising ‘Control.Monad.Trans.State.Lazy.$fApplicativeStateT’
    Probable fix: add INLINABLE pragma on ‘Control.Monad.Trans.State.Lazy.$w$cliftA2’

src/Rel8/Query/Evaluate.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Data.Functor.Bind.Class.$w$c<.>9’
      when specialising ‘Data.Functor.Bind.Class.$fApplyStateT6’
    Probable fix: add INLINABLE pragma on ‘Data.Functor.Bind.Class.$w$c<.>9’

src/Rel8/Query/Evaluate.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Data.Functor.Bind.Class.$w$c.>8’
      when specialising ‘Data.Functor.Bind.Class.$fApplyStateT9’
    Probable fix: add INLINABLE pragma on ‘Data.Functor.Bind.Class.$w$c.>8’

src/Rel8/Query/Evaluate.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Data.Functor.Bind.Class.$w$c<.9’
      when specialising ‘Data.Functor.Bind.Class.$fApplyStateT7’
    Probable fix: add INLINABLE pragma on ‘Data.Functor.Bind.Class.$w$c<.9’

src/Rel8/Query/Evaluate.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Control.Monad.Trans.State.Strict.$w$cliftA2’
      when specialising ‘Control.Monad.Trans.State.Strict.$fApplicativeStateT2’
    Probable fix: add INLINABLE pragma on ‘Control.Monad.Trans.State.Strict.$w$cliftA2’
[ 95 of 129] Compiling Rel8.Query.Each  ( src/Rel8/Query/Each.hs, dist/build/Rel8/Query/Each.o, dist/build/Rel8/Query/Each.dyn_o )
[ 96 of 129] Compiling Rel8.Query.Distinct ( src/Rel8/Query/Distinct.hs, dist/build/Rel8/Query/Distinct.o, dist/build/Rel8/Query/Distinct.dyn_o )
[ 97 of 129] Compiling Rel8.Schema.Context.Nullify ( src/Rel8/Schema/Context/Nullify.hs, dist/build/Rel8/Schema/Context/Nullify.o, dist/build/Rel8/Schema/Context/Nullify.dyn_o )
[ 98 of 129] Compiling Rel8.Table.Maybe ( src/Rel8/Table/Maybe.hs, dist/build/Rel8/Table/Maybe.o, dist/build/Rel8/Table/Maybe.dyn_o )
[ 99 of 129] Compiling Rel8.Table.These ( src/Rel8/Table/These.hs, dist/build/Rel8/Table/These.o, dist/build/Rel8/Table/These.dyn_o )

src/Rel8/Table/These.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Rel8.Table.Maybe.$w$s$fTaggablea_$ctappend’
      when specialising ‘Rel8.Table.Maybe.$fApplicativeMaybeTable_$s$fTaggablea_$ctappend’
    Probable fix: add INLINABLE pragma on ‘Rel8.Table.Maybe.$w$s$fTaggablea_$ctappend’
[100 of 129] Compiling Rel8.Query.Maybe ( src/Rel8/Query/Maybe.hs, dist/build/Rel8/Query/Maybe.o, dist/build/Rel8/Query/Maybe.dyn_o )

src/Rel8/Query/Maybe.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Control.Monad.Trans.State.Lazy.$w$cliftA2’
      when specialising ‘Control.Monad.Trans.State.Lazy.$fApplicativeStateT2’
      when specialising ‘Control.Monad.Trans.State.Lazy.$fApplicativeStateT’
    Probable fix: add INLINABLE pragma on ‘Control.Monad.Trans.State.Lazy.$w$cliftA2’
[101 of 129] Compiling Rel8.Query.Exists ( src/Rel8/Query/Exists.hs, dist/build/Rel8/Query/Exists.o, dist/build/Rel8/Query/Exists.dyn_o )
[102 of 129] Compiling Rel8.Table.Either ( src/Rel8/Table/Either.hs, dist/build/Rel8/Table/Either.o, dist/build/Rel8/Table/Either.dyn_o )
[103 of 129] Compiling Rel8.Query.These ( src/Rel8/Query/These.hs, dist/build/Rel8/Query/These.o, dist/build/Rel8/Query/These.dyn_o )
[104 of 129] Compiling Rel8.Query.Either ( src/Rel8/Query/Either.hs, dist/build/Rel8/Query/Either.o, dist/build/Rel8/Query/Either.dyn_o )
[105 of 129] Compiling Rel8.Kind.Context ( src/Rel8/Kind/Context.hs, dist/build/Rel8/Kind/Context.o, dist/build/Rel8/Kind/Context.dyn_o )
[106 of 129] Compiling Rel8.Table.Unreify ( src/Rel8/Table/Unreify.hs, dist/build/Rel8/Table/Unreify.o, dist/build/Rel8/Table/Unreify.dyn_o )
[107 of 129] Compiling Rel8.Table.NonEmpty ( src/Rel8/Table/NonEmpty.hs, dist/build/Rel8/Table/NonEmpty.o, dist/build/Rel8/Table/NonEmpty.dyn_o )
[108 of 129] Compiling Rel8.Table.List  ( src/Rel8/Table/List.hs, dist/build/Rel8/Table/List.o, dist/build/Rel8/Table/List.dyn_o )
[109 of 129] Compiling Rel8.Expr.Aggregate ( src/Rel8/Expr/Aggregate.hs, dist/build/Rel8/Expr/Aggregate.o, dist/build/Rel8/Expr/Aggregate.dyn_o )
[110 of 129] Compiling Rel8.Table.Aggregate ( src/Rel8/Table/Aggregate.hs, dist/build/Rel8/Table/Aggregate.o, dist/build/Rel8/Table/Aggregate.dyn_o )
[111 of 129] Compiling Rel8.Query.Aggregate ( src/Rel8/Query/Aggregate.hs, dist/build/Rel8/Query/Aggregate.o, dist/build/Rel8/Query/Aggregate.dyn_o )

src/Rel8/Query/Aggregate.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Rel8.Table.Opaleye.$waggregator’
      when specialising ‘Rel8.Table.Opaleye.aggregator1’
    Probable fix: add INLINABLE pragma on ‘Rel8.Table.Opaleye.$waggregator’
[112 of 129] Compiling Rel8.Query.List  ( src/Rel8/Query/List.hs, dist/build/Rel8/Query/List.o, dist/build/Rel8/Query/List.dyn_o )
[113 of 129] Compiling Rel8.Column.These ( src/Rel8/Column/These.hs, dist/build/Rel8/Column/These.o, dist/build/Rel8/Column/These.dyn_o )
[114 of 129] Compiling Rel8.Column.NonEmpty ( src/Rel8/Column/NonEmpty.hs, dist/build/Rel8/Column/NonEmpty.o, dist/build/Rel8/Column/NonEmpty.dyn_o )
[115 of 129] Compiling Rel8.Column.Maybe ( src/Rel8/Column/Maybe.hs, dist/build/Rel8/Column/Maybe.o, dist/build/Rel8/Column/Maybe.dyn_o )
[116 of 129] Compiling Rel8.Column.List ( src/Rel8/Column/List.hs, dist/build/Rel8/Column/List.o, dist/build/Rel8/Column/List.dyn_o )
[117 of 129] Compiling Rel8.Column.Either ( src/Rel8/Column/Either.hs, dist/build/Rel8/Column/Either.o, dist/build/Rel8/Column/Either.dyn_o )
[118 of 129] Compiling Rel8.Column      ( src/Rel8/Column.hs, dist/build/Rel8/Column.o, dist/build/Rel8/Column.dyn_o )
[119 of 129] Compiling Rel8.Generic.Rel8able ( src/Rel8/Generic/Rel8able.hs, dist/build/Rel8/Generic/Rel8able.o, dist/build/Rel8/Generic/Rel8able.dyn_o )
[120 of 129] Compiling Rel8.Generic.Construction.ADT ( src/Rel8/Generic/Construction/ADT.hs, dist/build/Rel8/Generic/Construction/ADT.o, dist/build/Rel8/Generic/Construction/ADT.dyn_o )
[121 of 129] Compiling Rel8.Generic.Construction ( src/Rel8/Generic/Construction.hs, dist/build/Rel8/Generic/Construction.o, dist/build/Rel8/Generic/Construction.dyn_o )
[122 of 129] Compiling Rel8.Table.HKD   ( src/Rel8/Table/HKD.hs, dist/build/Rel8/Table/HKD.o, dist/build/Rel8/Table/HKD.dyn_o )
[123 of 129] Compiling Rel8.Table.ADT   ( src/Rel8/Table/ADT.hs, dist/build/Rel8/Table/ADT.o, dist/build/Rel8/Table/ADT.dyn_o )
[124 of 129] Compiling Rel8.Table.Rel8able ( src/Rel8/Table/Rel8able.hs, dist/build/Rel8/Table/Rel8able.o, dist/build/Rel8/Table/Rel8able.dyn_o )
[125 of 129] Compiling Rel8.Type.Composite ( src/Rel8/Type/Composite.hs, dist/build/Rel8/Type/Composite.o, dist/build/Rel8/Type/Composite.dyn_o )
[126 of 129] Compiling Rel8.Column.Lift ( src/Rel8/Column/Lift.hs, dist/build/Rel8/Column/Lift.o, dist/build/Rel8/Column/Lift.dyn_o )
[127 of 129] Compiling Rel8.Column.ADT  ( src/Rel8/Column/ADT.hs, dist/build/Rel8/Column/ADT.o, dist/build/Rel8/Column/ADT.dyn_o )
[128 of 129] Compiling Rel8             ( src/Rel8.hs, dist/build/Rel8.o, dist/build/Rel8.dyn_o )
[129 of 129] Compiling Rel8.Generic.Rel8able.Test ( src/Rel8/Generic/Rel8able/Test.hs, dist/build/Rel8/Generic/Rel8able/Test.o, dist/build/Rel8/Generic/Rel8able/Test.dyn_o )
Preprocessing test suite 'tests' for rel8-1.0.0.1..
Building test suite 'tests' for rel8-1.0.0.1..
[1 of 1] Compiling Main             ( tests/Main.hs, dist/build/tests/tests-tmp/Main.o )

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$wmaybe’
      when specialising ‘Gen.maybe’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$wmaybe’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘GHC.Show.$fShowMaybe_$cshowsPrec’
      when specialising ‘GHC.Show.$fShowMaybe’
    Probable fix: add INLINABLE pragma on ‘GHC.Show.$fShowMaybe_$cshowsPrec’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘GHC.Show.$fShowMaybe_$cshow’
      when specialising ‘GHC.Show.$fShowMaybe’
    Probable fix: add INLINABLE pragma on ‘GHC.Show.$fShowMaybe_$cshow’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘GHC.Show.$fShowMaybe_$cshowsPrec’
      when specialising ‘GHC.Show.$fShowMaybe_$cshowList’
      when specialising ‘GHC.Show.$fShowMaybe’
    Probable fix: add INLINABLE pragma on ‘GHC.Show.$fShowMaybe_$cshowsPrec’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Range.$wlinearFrom’
      when specialising ‘Range.linearFrom’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Range.$wlinearFrom’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$c<*>’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$c<*>’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$wunicode’
      when specialising ‘Gen.unicode’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$wunicode’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘GHC.Real.$wfromIntegral’
      when specialising ‘fromIntegral’
    Probable fix: add INLINABLE pragma on ‘GHC.Real.$wfromIntegral’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$wbytes’
      when specialising ‘Gen.bytes’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$wbytes’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Range.$wlinearBounded’
      when specialising ‘Range.linearBounded’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Range.$wlinearBounded’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$wenum’
      when specialising ‘Gen.enum’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$wenum’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$w$cliftIO’
      when specialising ‘Hedgehog.Internal.Property.$fMonadIOPropertyT_$cliftIO’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$w$cliftIO’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Statement.Select.select1’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Statement.Select.select1’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$w$c>>=’
      when specialising ‘Hedgehog.Internal.Property.$fMonadPropertyT1’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$w$c>>=’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘diff’
    Probable fix: add INLINABLE pragma on ‘diff’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$w$c>>=’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT1’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$w$c>>=’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$wjust’
      when specialising ‘Gen.just’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$wjust’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘cover’
    Probable fix: add INLINABLE pragma on ‘cover’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘pretty-show-1.10:Text.Show.Pretty.ppShow’
    Probable fix: add INLINABLE pragma on ‘pretty-show-1.10:Text.Show.Pretty.ppShow’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Rel8.values’
    Probable fix: add INLINABLE pragma on ‘Rel8.values’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Serialize.$wlit’
      when specialising ‘Rel8.lit’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Serialize.$wlit’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Query.Each.$weach’
      when specialising ‘Rel8.each’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Query.Each.$weach’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Undefined.$wundefined’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Undefined.undefined’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Undefined.$wundefined’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘ghc-prim-0.6.1:GHC.Classes.$w$ccompare’
      when specialising ‘ghc-prim-0.6.1:GHC.Classes.$fOrd(,)_$ccompare’
    Probable fix: add INLINABLE pragma on ‘ghc-prim-0.6.1:GHC.Classes.$w$ccompare’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Opaleye.distinctspec1’
      when specialising ‘rel8-1.0.0.1:Rel8.Query.Distinct.distinct1’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Opaleye.distinctspec1’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Opaleye.binaryspec1’
      when specialising ‘rel8-1.0.0.1:Rel8.Query.Set.union1’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Opaleye.binaryspec1’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Data.Foldable.$wtraverse_’
      when specialising ‘Data.Foldable.traverse_’
    Probable fix: add INLINABLE pragma on ‘Data.Foldable.$wtraverse_’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$welement’
      when specialising ‘Gen.element’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$welement’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Maybe.$w$s$fTaggablea_$ctappend’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Maybe.$w$s$fTaggablea_$ctappend’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Query.List.$wcatListTable’
      when specialising ‘Rel8.catListTable’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Query.List.$wcatListTable’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$wevalM’
      when specialising ‘evalM’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$wevalM’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Expr.$w$cfromString’
      when specialising ‘rel8-1.0.0.1:Rel8.Expr.$fIsStringExpr_$cfromString’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Expr.$w$cfromString’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’
      when specialising ‘Hedgehog.Internal.Gen.$fFunctorGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$cp1Applicative’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’
      when specialising ‘Hedgehog.Internal.Gen.$fFunctorGenT_$c<$’
      when specialising ‘Hedgehog.Internal.Gen.$fFunctorGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$cp1Applicative’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$c<*>’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$c<*>’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cliftA2’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cliftA2’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$c*>’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$c*>’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cliftA2’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$c<*’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cliftA2’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘transformers-0.5.6.2:Control.Monad.Trans.Except.$fFunctorExceptT_$c<$’
      when specialising ‘Hedgehog.Internal.Property.$fFunctorTestT1’
      when specialising ‘Hedgehog.Internal.Property.$fFunctorTestT’
      when specialising ‘Hedgehog.Internal.Property.$fApplicativeTestT_$cp1Applicative’
      when specialising ‘Hedgehog.Internal.Property.$fApplicativeTestT’
    Probable fix: add INLINABLE pragma on ‘transformers-0.5.6.2:Control.Monad.Trans.Except.$fFunctorExceptT_$c<$’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$fApplicativeTestT3’
      when specialising ‘Hedgehog.Internal.Property.$fApplicativeTestT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$fApplicativeTestT3’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$fApplicativeTestT2’
      when specialising ‘Hedgehog.Internal.Property.$fApplicativeTestT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$fApplicativeTestT2’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$fAlternativePropertyT_$cliftA2’
      when specialising ‘Hedgehog.Internal.Property.$fApplicativeTestT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$fAlternativePropertyT_$cliftA2’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$fApplicativeTestT1’
      when specialising ‘Hedgehog.Internal.Property.$fApplicativeTestT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$fApplicativeTestT1’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$fApplicativePropertyT_$c<*’
      when specialising ‘Hedgehog.Internal.Property.$fApplicativeTestT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$fApplicativePropertyT_$c<*’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$fApplicativeTestT3’
      when specialising ‘Hedgehog.Internal.Property.$fMonadTestT’
      when specialising ‘Hedgehog.Internal.Property.$fMonadTestTestT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$fApplicativeTestT3’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’
      when specialising ‘Hedgehog.Internal.Gen.$fFunctorGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$cp1Applicative’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT_$cp1MonadIO’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’
      when specialising ‘Hedgehog.Internal.Gen.$fFunctorGenT_$c<$’
      when specialising ‘Hedgehog.Internal.Gen.$fFunctorGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$cp1Applicative’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT_$cp1MonadIO’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cfmap’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$c<*>’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT_$cp1MonadIO’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$c<*>’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cliftA2’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT_$cp1MonadIO’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cliftA2’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$c*>’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT_$cp1MonadIO’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$c*>’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cliftA2’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT_$c<*’
      when specialising ‘Hedgehog.Internal.Gen.$fApplicativeGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT_$cp1MonadIO’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fAlternativeGenT_$cliftA2’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$w$c>>=’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT1’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadGenT’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT_$cp1MonadIO’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$w$c>>=’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Gen.$fMMonadGenT_$clift’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT_$cliftIO’
      when specialising ‘Hedgehog.Internal.Gen.$fMonadIOGenT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Gen.$fMMonadGenT_$clift’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Hedgehog.Internal.Property.$w$cliftBase’
      when specialising ‘Hedgehog.Internal.Property.$fMonadBasebTestT1’
      when specialising ‘Hedgehog.Internal.Property.$fMonadBasebTestT’
      when specialising ‘Hedgehog.Internal.Property.$fMonadBaseControlbTestT_$cp1MonadBaseControl’
      when specialising ‘Hedgehog.Internal.Property.$fMonadBaseControlbTestT’
    Probable fix: add INLINABLE pragma on ‘Hedgehog.Internal.Property.$w$cliftBase’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Data.Map.Internal.$w$cshowsPrec’
      when specialising ‘Data.Map.Internal.$fShowMap_$cshowsPrec’
      when specialising ‘Data.Map.Internal.$fShowMap’
    Probable fix: add INLINABLE pragma on ‘Data.Map.Internal.$w$cshowsPrec’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘GHC.Show.$fShowMaybe_$cshowsPrec’
    Probable fix: add INLINABLE pragma on ‘GHC.Show.$fShowMaybe_$cshowsPrec’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fTablecontextt_$ctoColumns’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fTablecontextt’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fRecontextualizefromtott’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fTablecontextt_$ctoColumns’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fTablecontextt_$cfromColumns’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fTablecontextt’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fRecontextualizefromtott’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fTablecontextt_$cfromColumns’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$w$cp1ToExprs’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fToExprsxt_$cp1ToExprs’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$fToExprsxt’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Rel8able.$w$cp1ToExprs’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Maybe.$w$ctoColumns’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fTablecontextMaybeTable_$ctoColumns’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fTablecontextMaybeTable’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fToExprsMaybeTableMaybe_$cp1ToExprs’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fToExprsMaybeTableMaybe’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Maybe.$w$ctoColumns’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Maybe.$w$cfromColumns’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fTablecontextMaybeTable_$cfromColumns’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fTablecontextMaybeTable’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fToExprsMaybeTableMaybe_$cp1ToExprs’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fToExprsMaybeTableMaybe’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Maybe.$w$cfromColumns’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Maybe.$w$cfromResult’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fToExprsMaybeTableMaybe_$cfromResult’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fToExprsMaybeTableMaybe’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Maybe.$w$cfromResult’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fToExprsMaybeTableMaybe_$ctoResult’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fToExprsMaybeTableMaybe’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Maybe.$fToExprsMaybeTableMaybe_$ctoResult’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Serialize.$w$cfromResult’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Serialize.$fToExprsx(,)_$cfromResult’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Serialize.$fToExprsx(,)’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Serialize.$w$cfromResult’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.Serialize.$w$ctoResult’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Serialize.$fToExprsx(,)_$ctoResult’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.Serialize.$fToExprsx(,)’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.Serialize.$w$ctoResult’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘ghc-prim-0.6.1:GHC.Classes.$w$c==’
      when specialising ‘ghc-prim-0.6.1:GHC.Classes.$fEq(,)_$c==’
    Probable fix: add INLINABLE pragma on ‘ghc-prim-0.6.1:GHC.Classes.$w$c==’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘ghc-prim-0.6.1:GHC.Classes.$w$c<’
      when specialising ‘ghc-prim-0.6.1:GHC.Classes.$fOrd(,)_$c<’
    Probable fix: add INLINABLE pragma on ‘ghc-prim-0.6.1:GHC.Classes.$w$c<’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘GHC.Show.$w$cshowsPrec1’
      when specialising ‘GHC.Show.$fShow(,,)_$cshowsPrec’
      when specialising ‘GHC.Show.$fShow(,,)’
    Probable fix: add INLINABLE pragma on ‘GHC.Show.$w$cshowsPrec1’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘GHC.Show.$w$cshowsPrec2’
      when specialising ‘GHC.Show.$fShow(,,,)_$cshowsPrec’
      when specialising ‘GHC.Show.$fShow(,,,)’
    Probable fix: add INLINABLE pragma on ‘GHC.Show.$w$cshowsPrec2’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.List.$w$cp1Table’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fTablecontextListTable_$cp1Table’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fTablecontextListTable’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fToExprsListTable[]_$cp1ToExprs’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fToExprsListTable[]’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.List.$w$cp1Table’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.List.$w$creify’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fTablecontextListTable_$creify’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fTablecontextListTable’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fToExprsListTable[]_$cp1ToExprs’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fToExprsListTable[]’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.List.$w$creify’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.List.$w$cunreify’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fTablecontextListTable_$cunreify’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fTablecontextListTable’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fToExprsListTable[]_$cp1ToExprs’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fToExprsListTable[]’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.List.$w$cunreify’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘rel8-1.0.0.1:Rel8.Table.List.$fToExprsListTable[]_$cfromResult’
      when specialising ‘rel8-1.0.0.1:Rel8.Table.List.$fToExprsListTable[]’
    Probable fix: add INLINABLE pragma on ‘rel8-1.0.0.1:Rel8.Table.List.$fToExprsListTable[]_$cfromResult’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘exceptions-0.10.4:Control.Monad.Catch.$fMonadThrowExceptT_$cthrowM’
      when specialising ‘Hedgehog.Internal.Property.$fMonadThrowTestT1’
      when specialising ‘Hedgehog.Internal.Property.$fMonadThrowTestT’
      when specialising ‘Hedgehog.Internal.Property.$fMonadCatchTestT_$cp1MonadCatch’
      when specialising ‘Hedgehog.Internal.Property.$fMonadCatchTestT’
    Probable fix: add INLINABLE pragma on ‘exceptions-0.10.4:Control.Monad.Catch.$fMonadThrowExceptT_$cthrowM’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$fApplicativeWriterT_$cliftA2’
      when specialising ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$fApplicativeWriterT’
      when specialising ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$fMonadWriterT_$cp1Monad’
      when specialising ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$fMonadWriterT’
      when specialising ‘exceptions-0.10.4:Control.Monad.Catch.$fMonadThrowWriterT_$cp1MonadThrow’
      when specialising ‘exceptions-0.10.4:Control.Monad.Catch.$fMonadThrowWriterT’
      when specialising ‘Hedgehog.Internal.Property.$fMonadThrowTestT1’
      when specialising ‘Hedgehog.Internal.Property.$fMonadThrowTestT’
      when specialising ‘Hedgehog.Internal.Property.$fMonadCatchTestT_$cp1MonadCatch’
      when specialising ‘Hedgehog.Internal.Property.$fMonadCatchTestT’
    Probable fix: add INLINABLE pragma on ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$fApplicativeWriterT_$cliftA2’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$w$c*>’
      when specialising ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$fApplicativeWriterT2’
      when specialising ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$fApplicativeWriterT’
      when specialising ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$fMonadWriterT_$cp1Monad’
      when specialising ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$fMonadWriterT’
      when specialising ‘exceptions-0.10.4:Control.Monad.Catch.$fMonadThrowWriterT_$cp1MonadThrow’
      when specialising ‘exceptions-0.10.4:Control.Monad.Catch.$fMonadThrowWriterT’
      when specialising ‘Hedgehog.Internal.Property.$fMonadThrowTestT1’
      when specialising ‘Hedgehog.Internal.Property.$fMonadThrowTestT’
      when specialising ‘Hedgehog.Internal.Property.$fMonadCatchTestT_$cp1MonadCatch’
      when specialising ‘Hedgehog.Internal.Property.$fMonadCatchTestT’
    Probable fix: add INLINABLE pragma on ‘transformers-0.5.6.2:Control.Monad.Trans.Writer.Lazy.$w$c*>’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘exceptions-0.10.4:Control.Monad.Catch.$w$cthrowM1’
      when specialising ‘exceptions-0.10.4:Control.Monad.Catch.$fMonadThrowWriterT_$cthrowM’
      when specialising ‘exceptions-0.10.4:Control.Monad.Catch.$fMonadThrowWriterT’
      when specialising ‘Hedgehog.Internal.Property.$fMonadThrowTestT1’
      when specialising ‘Hedgehog.Internal.Property.$fMonadThrowTestT’
      when specialising ‘Hedgehog.Internal.Property.$fMonadCatchTestT_$cp1MonadCatch’
      when specialising ‘Hedgehog.Internal.Property.$fMonadCatchTestT’
    Probable fix: add INLINABLE pragma on ‘exceptions-0.10.4:Control.Monad.Catch.$w$cthrowM1’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘Data.Fixed.$fNumFixed_$c*’
      when specialising ‘Data.Fixed.$fNumFixed’
    Probable fix: add INLINABLE pragma on ‘Data.Fixed.$fNumFixed_$c*’

tests/Main.hs: warning: [-Wall-missed-specialisations]
    Could not specialise imported function ‘case-insensitive-1.2.1.0:Data.CaseInsensitive.Internal.$fShowCI_$cshowList’
      when specialising ‘case-insensitive-1.2.1.0:Data.CaseInsensitive.Internal.$fShowCI’
    Probable fix: add INLINABLE pragma on ‘case-insensitive-1.2.1.0:Data.CaseInsensitive.Internal.$fShowCI_$cshowList’
Linking dist/build/tests/tests ...
running tests
Running 1 test suites...
Test suite tests: RUNNING...
rel8
  Can SELECT TestTable:                    OK (0.07s)
      ✓ Can SELECT TestTable passed 100 tests.
        Empty     25% █████··············· ✓ 1%
        Singleton 47% █████████▍·········· ✓ 1%
        >1 row    53% ██████████▌········· ✓ 1%
  WHERE (Rel8.where_):                     OK (0.07s)
      ✓ WHERE (Rel8.where_) passed 100 tests.
        No results   22% ████▍··············· ✓ 1%
        Some results 78% ███████████████▌···· ✓ 1%
        All results  27% █████▍·············· ✓ 1%
  filter:                                  OK (0.08s)
      ✓ filter passed 100 tests.
        No results   20% ████················ ✓ 1%
        Some results 80% ████████████████···· ✓ 1%
        All results  15% ███················· ✓ 1%
  LIMIT (Rel8.limit):                      OK (0.08s)
      ✓ LIMIT (Rel8.limit) passed 100 tests.
        n == 0           25% █████··············· ✓ 1%
        n < length rows  65% █████████████······· ✓ 1%
        n == length rows 15% ███················· ✓ 1%
        n >= length rows 35% ███████············· ✓ 1%
  UNION (Rel8.union):                      OK (0.13s)
      ✓ UNION (Rel8.union) passed 100 tests.
  DISTINCT (Rel8.distinct):                OK (0.08s)
      ✓ DISTINCT (Rel8.distinct) passed 100 tests.
        Empty         32% ██████▍············· ✓ 1%
        Duplicates     5% █··················· ✓ 1%
        No duplicates 63% ████████████▌······· ✓ 1%
  EXISTS (Rel8.exists):                    OK (0.08s)
      ✓ EXISTS (Rel8.exists) passed 100 tests.
  Rel8.optional:                           OK (0.09s)
      ✓ Rel8.optional passed 100 tests.
  AND (&&.):                               OK (0.03s)
      ✓ AND (&&.) passed 100 tests.
  OR (||.):                                OK (0.03s)
      ✓ OR (||.) passed 100 tests.
  NOT (not_):                              OK (0.03s)
      ✓ NOT (not_) passed 100 tests.
  ifThenElse_:                             OK (0.02s)
      ✓ ifThenElse_ passed 100 tests.
  Cartesian product (<*>):                 OK (0.10s)
      ✓ Cartesian product (<*>) passed 100 tests.
  DBType instances
    Bool
      Bool:                                OK (0.03s)
          ✓ Bool passed 100 tests.
      Maybe Bool:                          OK (0.03s)
          ✓ Maybe Bool passed 100 tests.
    ByteString
      ByteString:                          OK (0.04s)
          ✓ ByteString passed 100 tests.
      Maybe ByteString:                    OK (0.04s)
          ✓ Maybe ByteString passed 100 tests.
    CI Lazy Text
      CI Lazy Text:                        OK (0.04s)
          ✓ CI Lazy Text passed 100 tests.
      Maybe CI Lazy Text:                  OK (0.04s)
          ✓ Maybe CI Lazy Text passed 100 tests.
    CI Text
      CI Text:                             OK (0.04s)
          ✓ CI Text passed 100 tests.
      Maybe CI Text:                       OK (0.04s)
          ✓ Maybe CI Text passed 100 tests.
    Day
      Day:                                 OK (0.03s)
          ✓ Day passed 100 tests.
      Maybe Day:                           OK (0.03s)
          ✓ Maybe Day passed 100 tests.
    Double
      Double:                              OK (0.03s)
          ✓ Double passed 100 tests.
      Maybe Double:                        OK (0.03s)
          ✓ Maybe Double passed 100 tests.
    Float
      Float:                               OK (0.03s)
          ✓ Float passed 100 tests.
      Maybe Float:                         OK (0.03s)
          ✓ Maybe Float passed 100 tests.
    Int32
      Int32:                               OK (0.03s)
          ✓ Int32 passed 100 tests.
      Maybe Int32:                         OK (0.01s)
          ✓ Maybe Int32 passed 100 tests.
    Int64
      Int64:                               OK (0.02s)
          ✓ Int64 passed 100 tests.
      Maybe Int64:                         OK (0.03s)
          ✓ Maybe Int64 passed 100 tests.
    Lazy ByteString
      Lazy ByteString:                     OK (0.04s)
          ✓ Lazy ByteString passed 100 tests.
      Maybe Lazy ByteString:               OK (0.04s)
          ✓ Maybe Lazy ByteString passed 100 tests.
    Lazy Text
      Lazy Text:                           OK (0.03s)
          ✓ Lazy Text passed 100 tests.
      Maybe Lazy Text:                     OK (0.02s)
          ✓ Maybe Lazy Text passed 100 tests.
    LocalTime
      LocalTime:                           OK (0.04s)
          ✓ LocalTime passed 100 tests.
      Maybe LocalTime:                     OK (0.03s)
          ✓ Maybe LocalTime passed 100 tests.
    Scientific
      Scientific:                          OK (0.03s)
          ✓ Scientific passed 100 tests.
      Maybe Scientific:                    OK (0.02s)
          ✓ Maybe Scientific passed 100 tests.
    Text
      Text:                                OK (0.03s)
          ✓ Text passed 100 tests.
      Maybe Text:                          OK (0.05s)
          ✓ Maybe Text passed 100 tests.
    TimeOfDay
      TimeOfDay:                           OK (0.03s)
          ✓ TimeOfDay passed 100 tests.
      Maybe TimeOfDay:                     OK (0.03s)
          ✓ Maybe TimeOfDay passed 100 tests.
    UTCTime
      UTCTime:                             OK (0.02s)
          ✓ UTCTime passed 100 tests.
      Maybe UTCTime:                       OK (0.02s)
          ✓ Maybe UTCTime passed 100 tests.
    UUID
      UUID:                                OK (0.03s)
          ✓ UUID passed 100 tests.
      Maybe UUID:                          OK (0.03s)
          ✓ Maybe UUID passed 100 tests.
  DBEq instances
    Bool
      Bool:                                OK (0.03s)
          ✓ Bool passed 100 tests.
            Equal     51% ██████████▏········· ✓ 1%
            Not Equal 49% █████████▊·········· ✓ 1%
      Maybe Bool:                          OK (0.02s)
          ✓ Maybe Bool passed 100 tests.
            Equal     48% █████████▌·········· ✓ 1%
            Not Equal 52% ██████████▍········· ✓ 1%
    Int32
      Int32:                               OK (0.03s)
          ✓ Int32 passed 100 tests.
            Equal      1% ▏··················· ✓ 1%
            Not Equal 99% ███████████████████▊ ✓ 1%
      Maybe Int32:                         FAIL (0.06s)
          ✗ Maybe Int32 failed 
            after 100 tests.
          ⚠ Equal       0% ···················· ✗ 1%
            Not Equal 100% ████████████████████ ✓ 1%
          
                ┏━━ tests/Main.hs ━━━
            448 ┃ testDBEq :: IO TmpPostgres.DB -> TestTree
            449 ┃ testDBEq getTestDatabase = testGroup "DBEq instances"
            450 ┃   [ dbEqTest "Bool" Gen.bool
            451 ┃   , dbEqTest "Int32" $ Gen.integral @_ @Int32 Range.linearBounded
            452 ┃   , dbEqTest "Int64" $ Gen.integral @_ @Int64 Range.linearBounded
            453 ┃   , dbEqTest "Text" $ Gen.text (Range.linear 0 10) Gen.unicode
            454 ┃   ]
            455 ┃ 
            456 ┃   where
            457 ┃     dbEqTest :: (Eq a, Show a, Rel8.DBEq a) => TestName -> Gen a -> TestTree
            458 ┃     dbEqTest name generator = testGroup name
            459 ┃       [ databasePropertyTest name (t generator) getTestDatabase
            460 ┃       , databasePropertyTest ("Maybe " <> name) (t (Gen.maybe generator)) getTestDatabase
            461 ┃       ]
            462 ┃ 
            463 ┃     t :: forall a. (Eq a, Show a, Rel8.Sql Rel8.DBEq a)
            464 ┃       => Gen a
            465 ┃       -> ((Connection -> TestT IO ()) -> PropertyT IO ())
            466 ┃       -> PropertyT IO ()
            467 ┃     t generator transaction = do
            468 ┃       (x, y) <- forAll (liftA2 (,) generator generator)
            469 ┃ 
            470 ┃       transaction \connection -> do
            471 ┃         [res] <- liftIO $ Rel8.select connection $ pure $ Rel8.litExpr x Rel8.==. Rel8.litExpr y
            472 ┃         res === (x == y)
            473 ┃ 
            474 ┃         cover 1 "Equal" $ x == y
                ┃         ^^^^^^^^^^^^^^^^^^^^^^^^
                ┃         │ Failed (0% coverage)
            475 ┃         cover 1 "Not Equal" $ x /= y
          
            Labels not sufficently covered after TestCount 100 tests
          
        Use '--hedgehog-replay "Size 0 Seed 2271536934144735252 8891934970894135461"' to reproduce.
    Int64
      Int64:                               OK (0.04s)
          ✓ Int64 passed 100 tests.
            Equal      1% ▏··················· ✓ 1%
            Not Equal 99% ███████████████████▊ ✓ 1%
      Maybe Int64:                         FAIL (0.06s)
          ✗ Maybe Int64 failed 
            after 100 tests.
          ⚠ Equal       0% ···················· ✗ 1%
            Not Equal 100% ████████████████████ ✓ 1%
          
                ┏━━ tests/Main.hs ━━━
            448 ┃ testDBEq :: IO TmpPostgres.DB -> TestTree
            449 ┃ testDBEq getTestDatabase = testGroup "DBEq instances"
            450 ┃   [ dbEqTest "Bool" Gen.bool
            451 ┃   , dbEqTest "Int32" $ Gen.integral @_ @Int32 Range.linearBounded
            452 ┃   , dbEqTest "Int64" $ Gen.integral @_ @Int64 Range.linearBounded
            453 ┃   , dbEqTest "Text" $ Gen.text (Range.linear 0 10) Gen.unicode
            454 ┃   ]
            455 ┃ 
            456 ┃   where
            457 ┃     dbEqTest :: (Eq a, Show a, Rel8.DBEq a) => TestName -> Gen a -> TestTree
            458 ┃     dbEqTest name generator = testGroup name
            459 ┃       [ databasePropertyTest name (t generator) getTestDatabase
            460 ┃       , databasePropertyTest ("Maybe " <> name) (t (Gen.maybe generator)) getTestDatabase
            461 ┃       ]
            462 ┃ 
            463 ┃     t :: forall a. (Eq a, Show a, Rel8.Sql Rel8.DBEq a)
            464 ┃       => Gen a
            465 ┃       -> ((Connection -> TestT IO ()) -> PropertyT IO ())
            466 ┃       -> PropertyT IO ()
            467 ┃     t generator transaction = do
            468 ┃       (x, y) <- forAll (liftA2 (,) generator generator)
            469 ┃ 
            470 ┃       transaction \connection -> do
            471 ┃         [res] <- liftIO $ Rel8.select connection $ pure $ Rel8.litExpr x Rel8.==. Rel8.litExpr y
            472 ┃         res === (x == y)
            473 ┃ 
            474 ┃         cover 1 "Equal" $ x == y
                ┃         ^^^^^^^^^^^^^^^^^^^^^^^^
                ┃         │ Failed (0% coverage)
            475 ┃         cover 1 "Not Equal" $ x /= y
          
            Labels not sufficently covered after TestCount 100 tests
          
        Use '--hedgehog-replay "Size 0 Seed 4683194437231057052 14291057619312927273"' to reproduce.
    Text
      Text:                                OK (0.04s)
          ✓ Text passed 100 tests.
            Equal     16% ███▏················ ✓ 1%
            Not Equal 84% ████████████████▊··· ✓ 1%
      Maybe Text:                          OK (0.10s)
          ✓ Maybe Text passed 100 tests.
            Equal     10% ██·················· ✓ 1%
            Not Equal 90% ██████████████████·· ✓ 1%
  TestTable equality:                      OK (0.02s)
      ✓ TestTable equality passed 100 tests.
        Equal     14% ██▊················· ✓ 1%
        Not Equal 86% █████████████████▏·· ✓ 1%
  FromString:                              OK (0.03s)
      ✓ FromString passed 100 tests.
  catMaybeTable:                           OK (0.08s)
      ✓ catMaybeTable passed 100 tests.
  catMaybe:                                OK (0.06s)
      ✓ catMaybe passed 100 tests.
  maybeTable:                              OK (0.09s)
      ✓ maybeTable passed 100 tests.
  Nested TestTables:                       OK (0.08s)
      ✓ Nested TestTables passed 100 tests.
  MaybeTable (<*>):                        OK (0.26s)
      ✓ MaybeTable (<*>) passed 100 tests.
  Logical operator fixities:               OK (0.03s)
      ✓ Logical operator fixities passed 100 tests.
  Can UPDATE TestTable:                    OK (0.10s)
      ✓ Can UPDATE TestTable passed 100 tests.
        Empty     44% ████████▊··········· ✓ 1%
        Singleton 66% █████████████▏······ ✓ 1%
        >1 row    34% ██████▊············· ✓ 1%
  Can DELETE TestTable:                    OK (0.09s)
      ✓ Can DELETE TestTable passed 100 tests.
  Can SELECT nested pairs:                 OK (0.07s)
      ✓ Can SELECT nested pairs passed 100 tests.
  Can SELECT Arrays (with aggregation):    OK (0.18s)
      ✓ Can SELECT Arrays (with aggregation) passed 100 tests.
  Can nest MaybeTable within other tables: OK (0.05s)
      ✓ Can nest MaybeTable within other tables passed 100 tests.

2 out of 68 tests failed (5.47s)
Test suite tests: FAIL
Test suite logged to: dist/test/rel8-1.0.0.1-tests.log
0 of 1 test suites (0 of 1 test cases) passed.
builder for '/nix/store/z3266iw8a1hlkc5jk5jmwv0x9lhdh8na-rel8-1.0.0.1.drv' failed with exit code 1

Wherefore the `c` in the docs?

Hello there. I really enjoyed the talk on rel8 from Zurihac and am currently excitedly reading documentation. I noticed something a bit confusing in the tutorial section:

image

There's a c argument that shows up seemingly without further explanation in the docs. From reading the Hackage docs I can see this is supposed to be the database connection, but I think it'd be handy to mention this at least in passing. Alternatively, you could just name it more suggestively: conn or connection or whatever.

Failure to build with `opaleye-0.9.3.0`

It looks like opaleye removed the stateQueryArr function in 0.9.3.0 (cf. tomjaguarpaw/haskell-opaleye@01f2b37).

rel8 now fails to compile with the following error:

Preprocessing library for rel8-1.3.1.0..
Building library for rel8-1.3.1.0..
[  7 of 133] Compiling Rel8.Query.Opaleye

/[...]/src//Rel8/Query/Opaleye.hs:51:15: error:
    Not in scope: ‘Opaleye.stateQueryArr’
    Perhaps you meant one of these:
      ‘Opaleye.runStateQueryArr’ (imported from Opaleye.Internal.QueryArr),
      data constructor ‘Opaleye.QueryArr’ (imported from Opaleye.Internal.QueryArr),
      ‘Opaleye.unQueryArr’ (imported from Opaleye.Internal.QueryArr)
    Neither ‘Opaleye.Internal.QueryArr’ nor ‘Opaleye.Internal.Tag’ exports ‘stateQueryArr’.
   |
51 | mapping f q = Opaleye.stateQueryArr $ \_ tag ->
   |               ^^^^^^^^^^^^^^^^^^^^^

/[...]/src/Rel8/Query/Opaleye.hs:63:3: error:
    Not in scope: ‘Opaleye.stateQueryArr’
    Perhaps you meant one of these:
      ‘Opaleye.runStateQueryArr’ (imported from Opaleye.Internal.QueryArr),
      data constructor ‘Opaleye.QueryArr’ (imported from Opaleye.Internal.QueryArr),
      ‘Opaleye.unQueryArr’ (imported from Opaleye.Internal.QueryArr)
    Neither ‘Opaleye.Internal.QueryArr’ nor ‘Opaleye.Internal.Tag’ exports ‘stateQueryArr’.
   |
63 |   Opaleye.stateQueryArr $ \_ tag ->
   |   ^^^^^^^^^^^^^^^^^^^^^

cf. commercialhaskell/stackage#6653

TableSchema to CREATE TABLE?

I'd like to pretend I don't have a database at all because I don't understand SQL, and am hoping rel8 can give me the SQL necessary to create the db/table it will talk to. Is this possible given a TableSchema?

Showing the query for insert/update/delete

Would it be possible to add functions like showQuery, but for operations other than select?

A couple reasons:

  • At the moment I would like it because I'm curious about how the update function works (what does the query look like when you don't update all of the columns?).
  • I think I might like to start logging queries at some point.

LIKE and ILIKE

Thanks for the lib, I'm enjoying using it a lot.

One question, though.
I don't seem to find a way to express a LIKE or ILIKE query.

If not supported directly, as it seems, what would be the best workaround?

Thanks

MaybeTable test is flaky

Observed this failure on x86_64-darwin, but re-running the test suite made it pass, so this test case may be flaky (or maybe have locale-specific edge cases as it involves sorting?).

  MaybeTable (<*>):                            FAIL (0.15s)
      ✗ MaybeTable (<*>) failed at tests/Main.hs:587:85
        after 84 tests.
      
            ┏━━ tests/Main.hs ━━━
        586 ┃ testMaybeTableApplicative :: IO TmpPostgres.DB -> TestTree
        587 ┃ testMaybeTableApplicative = databasePropertyTest "MaybeTable (<*>)" \transaction -> evalM do
        588 ┃   rows1 <- genRows
        589 ┃   rows2 <- genRows
        590 ┃ 
        591 ┃   transaction do
        592 ┃     selected <- lift do
        593 ┃       statement () $ Rel8.select do
        594 ┃         as <- Rel8.optional (Rel8.values (Rel8.lit <$> rows1))
        595 ┃         bs <- Rel8.optional (Rel8.values (Rel8.lit <$> rows2))
        596 ┃         pure $ liftA2 (,) as bs
        597 ┃ 
        598 ┃     case (rows1, rows2) of
        599 ┃       ([], []) -> selected === [Nothing]
        600 ┃       ([], bs) -> selected === (Nothing <$ bs)
        601 ┃       (as, []) -> selected === (Nothing <$ as)
        602 ┃       (as, bs) -> sort selected === sort (Just <$> liftA2 (,) as bs)
            ┃       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            ┃       │ ━━━ Exception (QueryError) ━━━
            ┃       │ QueryError "SELECT\nCAST(CASE WHEN ((\"rebind0_2\") IS NULL) OR ((\"rebind0_6\") IS NULL) THEN CAST(NULL AS bool) ELSE (\"rebind0_2\") AND (\"rebind0_6\") END AS bool) as \"isJust\",\nCAST(CASE WHEN (CASE WHEN ((\"rebind0_2\") IS NULL) OR ((\"rebind0_6\") IS NULL) THEN CAST(NULL AS bool) ELSE (\"rebind0_2\") AND (\"rebind0_6\") END) IS NOT NULL THEN \"values0_1\" ELSE NULL END AS text) as \"Just/_1/testTableColumn1\",\nCAST(CASE WHEN (CASE WHEN ((\"rebind0_2\") IS NULL) OR ((\"rebind0_6\") IS NULL) THEN CAST(NULL AS bool) ELSE (\"rebind0_2\") AND (\"rebind0_6\") END) IS NOT NULL THEN \"values1_1\" ELSE NULL END AS bool) as \"Just/_1/testTableColumn2\",\nCAST(CASE WHEN (CASE WHEN ((\"rebind0_2\") IS NULL) OR ((\"rebind0_6\") IS NULL) THEN CAST(NULL AS bool) ELSE (\"rebind0_2\") AND (\"rebind0_6\") END) IS NOT NULL THEN \"values0_5\" ELSE NULL END AS text) as \"Just/_2/testTableColumn1\",\nCAST(CASE WHEN (CASE WHEN ((\"rebind0_2\") IS NULL) OR ((\"rebind0_6\") IS NULL) THEN CAST(NULL AS bool) ELSE (\"rebind0_2\") AND (\"rebind0_6\") END) IS NOT NULL THEN \"values1_5\" ELSE NULL END AS bool) as \"Just/_2/testTableColumn2\"\nFROM (SELECT *\n      FROM\n      (SELECT *\n       FROM\n       (SELECT\n        0) as \"T1\"\n       LEFT OUTER JOIN\n       (SELECT\n        TRUE as \"rebind0_2\",\n        *\n        FROM (SELECT\n              *\n              FROM (SELECT \"column1\" as \"values0_1\",\n                           \"column2\" as \"values1_1\"\n                    FROM\n                    (VALUES\n                     (CAST(E'\\U0001287c\\U0008b520\\U0006181e\\U000b785e\240\176\128\142\\0\\U000ed9b7\\U0004b3ab\\U000ee815' AS text),CAST(TRUE AS bool)),\n                     (CAST(E'\240\165\163\153\\U00060715' AS text),CAST(TRUE AS bool)),\n                     (CAST(E'\230\142\137\\U0006233c\\U00051f8f\\U0004edf4\\U000c0800\\U0010e4e1' AS text),CAST(TRUE AS bool))) as \"V\") as \"T1\") as \"T1\") as \"T2\"\n       ON\n       TRUE) as \"T1\"\n      LEFT OUTER JOIN\n      LATERAL\n      (SELECT\n       TRUE as \"rebind0_6\",\n       *\n       FROM (SELECT\n             *\n             FROM (SELECT \"column1\" as \"values0_5\",\n                          \"column2\" as \"values1_5\"\n                   FROM\n                   (VALUES\n                    (CAST(E'\\U000a865a\\U00094a4a\\U0001e0c0\\U000569d1\\U000a8170' AS text),CAST(TRUE AS bool)),\n                    (CAST(E'\\U000b0a55\\U0003b46e\234\130\142\\U0006887f\\U0008a8e5\\U00046460\240\159\143\187\\U0004c6bf\\U000b987c' AS text),CAST(TRUE AS bool)),\n                    (CAST(E'\\U0009dd64\\U00055d18\\U0007d3dc\\U00095b3a\240\161\141\164' AS text),CAST(TRUE AS bool)),\n                    (CAST(E'\\U000ee282\\U000f25e8\240\162\134\146\\U0001ebe3\\U000d3641\\U0001966f\\U000914c5\\U0007c268\\U000342b9' AS text),CAST(TRUE AS bool)),\n                    (CAST(E'\\U000ea95f\\U00067448\240\172\172\149\\U00069cec' AS text),CAST(TRUE AS bool))) as \"V\") as \"T1\") as \"T1\") as \"T2\"\n      ON\n      TRUE) as \"T1\"" [] (ResultError (ServerError "22021" "invalid byte sequence for encoding \"UTF8\": 0x00" Nothing Nothing))
        603 ┃   where
        604 ┃     genRows :: PropertyT IO [TestTable Result]
        605 ┃     genRows = forAll do
        606 ┃       Gen.list (Range.linear 0 10) $ liftA2 TestTable (Gen.text (Range.linear 0 10) Gen.unicode) (pure True)
      
        This failure can be reproduced by running:
        > recheck (Size 83) (Seed 17452076655856458487 15436597684825125903) MaybeTable (<*>)
      
    Use '--hedgehog-replay "Size 83 Seed 17452076655856458487 15436597684825125903"' to reproduce.
    
    Use -p '/MaybeTable (<*>)/' to rerun this test only.

Unable to select from functions

As mentioned by @ocharles here, it's not yet possible to select from a function result. This is something that will be fairly critical for constructing more complex JSON-related queries.

A general library for higher-kinded data

Rel8 defines the term "higher-kinded data" as:

Higher-kinded data types are data types of the pattern:

data MyType f =
  MyType { field1 :: Column f T1 OR HK1 f
         , field2 :: Column f T2 OR HK2 f
         , ...
         , fieldN :: Column f Tn OR HKn f
         }

where Tn is any Haskell type, and HKn is any higher-kinded type.

Aside from the specific detail of the Column type family, this notion seems very general! Do y'all think there's any potential for a library that would help others replicate the pattern for other applications? (For example, I have in mind a similar sort of approach to filesystem storage, with database rows and fields corresponding to directories and files.)

Build on GHC 9

I don't think we can release without knowing we're compatible with the latest GHC

rel8 relies on undefined behavior of ORDER BY

Hello, this library is really cool. The best feature is that it can return trees of data instead of just tables.

But I noticed that the SQL it generates relies on undefined (or unspecified?) behavior of PostgreSQL, with regards to ORDER BY and LIMIT and ARRAY_AGG.

Here is an example query with ORDER BY and LIMIT:

SELECT name
FROM author
ORDER BY name
LIMIT 5

If this is changed to:

SELECT name
FROM
    (SELECT *
    FROM author
    ORDER BY name
    ) T1
LIMIT 5

then this is no longer the same query. Even though the inner SELECT has an ORDER BY clause, once it is selected from by the outer select, it is treated as an unordered relation, and the rows may result in any order. So the LIMIT clause will choose an arbitrary 5 rows. In practice, it seems that PostgreSQL will always returned the "expected" results for this query, but it is not guaranteed. The general rule of thumb is that LIMIT clause only makes sense when attached directly to an ORDER BY clause

And now for ARRAY_AGG there is a similar issue.

Here is an example query:

SELECT ARRAY_AGG(name)
FROM
    (SELECT *
    FROM author
    ORDER BY name
    ) T1;

This query doesn't do what we want. PostgreSQL aggregate functions aren't influenced by the ORDER BY clause that we have here, and so the result can be that the elements will be in any arbitrary order. The correct version of this query is this:

SELECT ARRAY_AGG(name ORDER BY name)
FROM
    (SELECT *
    FROM author
    ) T1;

If we want a LIMIT clause then we actually need two ORDER BY clauses like this:

SELECT ARRAY_AGG(name ORDER BY name)
FROM
    (SELECT *
    FROM author
    ORDER BY name
    LIMIT 5
    ) T1;

Also in these examples, even with the "incorrect" ARRAY_AGG query, it seems that in practice PostgreSQL will always return the "expected" result, but again this is not guaranteed.

I am not sure when these types of "incorrect" queries are likely to give incorrect results in practice (it may be never), but a good guess is when the queries become very complicated (go beyond the from_collapse_limit) or involve parallel scans.

Generated left-join is too complicated for Postgres to plan well

Hi folks,

My colleague @tstat and I were playing around with the library for the first time and we ran into a performance issue with a generated query that may or may not be totally expected. I understand that translating monadic syntax to SQL queries is perhaps going to be unavoidably "for-loopy" at times, so please feel free to close this issue as a #wontfix, although if that's the case I think we could put together some documentation that mention some known performance gotchas so that users won't necessarily have to examine plan output themselves.

Anyways, the query we were interested in writing with rel8 was a simple left-join. The schema is unimportant here, but let me know if it would be helpful to provide a repo that reproduces this issue exactly. (I think it will be clear enough from the following high-level description).

We have some students table, and students have first and last names, and we're interested in pairing students whose first name maybe matches the last name of another student:

select *
from students s1
left join students s2 on s1.first = s2.last;

This generates the following plan:

 Hash Left Join  (cost=2.35..4.78 rows=60 width=114)
   Hash Cond: (s1.first = s2.last)
   ->  Seq Scan on students s1  (cost=0.00..1.60 rows=60 width=57)
   ->  Hash  (cost=1.60..1.60 rows=60 width=57)
         ->  Seq Scan on students s2  (cost=0.00..1.60 rows=60 width=57)

In rel8, we translated this as:

s1 <- each studentsSchema
s2 <- optional do
  s2 <- each studentsSchema
  where_ (first s1 ==. last s2)
  pure s2
pure (s1, s2)

which generated a messier version of the following query:

select *
from students s1
cross join lateral (
  select *
  from (select 0) t1
  left outer join (
    select *
    from students s2
    where s1.first = s2.last
  ) t2 on true
) t2;

Unfortunately, Postgres' optimizer does not seem to consider a hash join in this case, and falls back to a much more expensive nested loop join:

 Nested Loop  (cost=0.00..109.00 rows=60 width=118)
   ->  Seq Scan on students s1  (cost=0.00..1.60 rows=60 width=57)
   ->  Nested Loop Left Join  (cost=0.00..1.77 rows=1 width=61)
         ->  Result  (cost=0.00..0.01 rows=1 width=0)
         ->  Seq Scan on students s2  (cost=0.00..1.75 rows=1 width=57)
               Filter: (s1.first = last)

Curiously, this is not merely due to the existence of a lateral join with a pushed-in where-clause. We tried rewriting the original SQL in this style:

select *
from students s1
left join lateral (
  select *
  from students s2
  where s1.first = s2.last
) t2 on true;

and in this case Postgres did again consider the hash join:

 Hash Left Join  (cost=2.35..4.78 rows=60 width=114)
   Hash Cond: (s1.first = s2.last)
   ->  Seq Scan on students s1  (cost=0.00..1.60 rows=60 width=57)
   ->  Hash  (cost=1.60..1.60 rows=60 width=57)
         ->  Seq Scan on students s2  (cost=0.00..1.60 rows=60 width=57)

Better docs on how to write Projections

The INSERT/UPSERT docs currently don’t describe how to write a Projection.

Following the type in the reference leads to

type Projection a b = Transpose (Field a) a -> Transpose (Field a) b 

where Transpose is an associated type of the Table class, which has over a dozen instances, so it’s very hard to figure out how a Projection would actually look like in practice.

How do I check whether a row is contained in a `ListTable`?

I would like to have a function with the following signature

ListTable Expr (f Expr) -> f Expr -> Expr Bool

which checks whether the second argument is contained in the list table.

Is this something which is achievable with the provided API? How could I do that?

Dealing with GENERATED ALWAYS columns?

I've got a column in my database that is created via:

ALTER TABLE discovery
    ADD COLUMN search tsvector
    GENERATED ALWAYS AS ...

which I'd like to be able to query on. I've thus added it to my rel8 schema:

data Tsvector = Tsvector
  deriving (Eq, Ord, Show)

instance DBEq Tsvector
instance DBOrd Tsvector

instance DBType Tsvector where
  typeInformation = TypeInformation
    { encode = const $ Prim.ConstExpr $ Prim.DefaultLit
    , decode = Decode.custom $ \_ _ -> pure Tsvector
    , typeName = "tsvector"
    }


data Discovery f = Discovery
  { d_docId :: Column f DocId
  , d_search :: Column f Tsvector
  }
  deriving stock Generic
  deriving anyclass Rel8able

There are two problems with this:

  1. When working with UPDATE statements, rel8 generates SQL like:
UPDATE discovery SET ..., search = search;

which postgres complains about; this must have value DEFAULT. I can use unsafeDefault to fill this in successfully (but it's a bit annoying!)

  1. When working with INSERT statements, rel8 generates SQL like:
INSERT INTO discovery VALUES (...., CAST(DEFAULT as tsvector));

which also fails (DEFAULT is not allowed in this context), however, I can't figure out how to sidestep this problem; rel8 seems to insist on an explicit cast in inserts.


Is there a better way of working with GENERATED ALWAYS columns? I'd like to be able to select this field, but have it ignored from all updates and inserts.

Expand OnConflict type to express "on conflict do update"

There are some things you can put in an on conflict clause that are not currently expressible with the OnConflict type, notably the "on conflict do update" SQL, which allows an INSERT that would violate a constraint to automatically convert into an UPDATE instead.

One example of a postgresql-simple query in my application that I cannot write with rel8:

insert into tc.stripe_invoice
    ( stripe_invoice_id
    , live_mode
    , stripe_customer_id
    , finalized_at
    , invoice_url
    )
values (?, ?, ?, ?, ?)
on conflict on constraint stripe_invoice_pkey do update
    set finalized_at = excluded.finalized_at
      , invoice_url  = excluded.invoice_url

It seems like it might be possible to expand rel8 to accommodate this in a type-safe way, but short of that, perhaps there could be an escape hatch here to permit writing the on-conflict clause manually?

Rename runAggregation -> sequenceAggregate

runAggregation seems a bit too general, and might lead people into thinking that the aggregation has been performed. I think sequenceAggregate might be a better name, as it's familiar when compared to sequenceA :: f (g a) -> g (f a)

How to use nextval with a newtyped ID?

I have the following table:

newtype UserId = UserId { toInt32 :: Int32 }
  deriving newtype (DBEq, DBType, Eq, Show)

deriving newtype instance DBType (PasswordHash a)

data User f = User
  { userId :: Column f UserId,
    userName :: Column f Text,
    userPassword :: Column f (PasswordHash Bcrypt)
  }
  deriving stock (Generic)
  deriving anyclass (Rel8able)

And I'm trying to figure out how to insert a user. I have this snippet in a Yesod Handler

    hashed <- liftIO <| hashPassword <| mkPassword password
    let user = User {
          userId = nextval "user_id_seq",
          userName = lit username,
          userPassword = lit hashed
        }
    Yesoder conn <- getYesod
    liftIO $ run (insertUser user) conn
    pure "registered"

But I'm getting

    • Couldn't match type ‘GHC.Int.Int64’ with ‘UserId’
      Expected: Column Expr UserId
        Actual: Expr GHC.Int.Int64
    • In the ‘userId’ field of a record
      In the expression:
        User
          {userId = nextval "user_id_seq", userName = lit username,
           userPassword = lit hashed}
      In an equation for ‘user’:
          user
            = User
                {userId = nextval "user_id_seq", userName = lit username,
                 userPassword = lit hashed}
   |
87 |             userId = nextval "user_id_seq",
   |                      ^^^^^^^^^^^^^^^^^^^^^

I thought I might be able to do something like UserId <$> nextval "user_id_seq" to obtain an Expr UserId, but Expr doesn't have a Functor instance. I only have the fuzziest understanding of how expr works, so I assume there's some good reason for this. On reflection this probably doesn't make sense.

How do I handle this correctly? It seems like a pretty foundational use case.

Is Template Haskell `Rel8able` deriving worth having?

Currently we derive Rel8able by piggy-backing off a Generic instance. This is fine, but I wonder if we should also have a deriveRel8able Template Haskell function. My theory: overall faster compilation due to not needing a Generic instance at all, and possibly a more efficient implementation.

Failed to compile rel8 with GHC 8.10.3

rel8: 1.0.0.0
GHC: 8.10.3
OS: windows 10
Error details:

rel8                         > src\Rel8\Type\Tag.hs:96:7: error:
rel8                         >     • Couldn't match type ‘Text’ with ‘Tag’
rel8                         >         arising from the coercion of the method ‘typeInformation’
rel8                         >           from type ‘Rel8.Type.Information.TypeInformation Text’
rel8                         >             to type ‘Rel8.Type.Information.TypeInformation Tag’
rel8                         >     • When deriving the instance for (DBType Tag)
rel8                         >    |
rel8                         > 96 |     , DBType, DBEq, DBOrd
rel8                         >    |       ^^^^^^
rel8                         >

Functions with named parameters

I watched Oliver's Zurihac talk this morning and I've already switched a few postgresql-simple queries over to rel8 😄

There is one that I don't know how to write well:

select token_id, token_secret
from tc.admin_log_in( p_username := ?,
                      p_password := ? )

I believe I could write this using function (I had not trouble doing this to implement another query that calls crypt), but I would have to specify the arguments positionally, which is the sort of error-prone thing I'm trying to avoid. Is there a recommended way to generate the named argument syntax using :=?

Encoder for `Infinity` is wrong

> showQuery $ pure $ lit (1/0 :: Double)
"SELECT\nCAST(CAST(1.79769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216e308 AS float8) AS float8) as \"anon\"\nFROM LATERAL\n     (SELECT\n      0) as \"T1\""

This should just be Infinity.

The same is true for 0/0 (NaN) and -1/0 (-Infinity).

Build failures with latest opaleye (0.9.1 and 0.9.2)

rel8-1.3.0.0 does not build with opaleye-0.9.1.0 (released two days ago) or opaleye-0.9.2.0 (released yesterday).

These versions are in bounds, so a metadata revision would be appropriate.

opaleye 0.9.0.0 can stay in bounds.

Should Rel8 functions be in a curry-friendly (haskell style) or infix-friendly (sql / operator style) argument order?

This was discussed offline at some point, but I thought I'd just double-check that this is really what we want? The feature is still brand new so it seems worth getting it right.

A colleague made the mistake of assuming ilike takes arguments in the same order as postgresql defines. I can easily see myself doing the same and being confused about why the query result are "wrong". I hardly spend any time looking at documentation for something as simple and familiar as like.

Taking two possible patterns for using ilike:

filter (ilike "Rel%" . packageName) =<< each haskellPackages

and

do
  package <- each haskellPackages
  where_ ("Rel%" `ilike` packageName package)

Do we really lose much with the unflipped version?

filter ((`ilike` "Rel%") . packageName) =<< each haskellPackages

and

do
  package <- each haskellPackages
  where_ (packageName package `ilike` "Rel%")

Rename coalesce

coalesce is the name of a general function in SQL, but coalesce :: Expr (Maybe Bool) -> Expr Bool is a very specific usage of it. I think we should rename our coalesce.

Mention DuplicateRecordFields in the documentation

Mention DuplicateRecordFields in the documentation. For example Insert, Delete and Update both have the field returning and it's a pain to disambiguate the correct field without DuplicateRecordFields.

Apply Aggregate is broken

Thanks to help from @tomjaguarpaw, I think I can finally conclude that Apply Aggregate won't work:

aggregate $ values [lit True, lit False] >>= \x -> pure ((x &&.) <$> Rel8.or x)

produces

SELECT
("values0_1") AND ("result0_2") as "anon"
FROM (SELECT
      *
      FROM (SELECT
            BOOL_OR("inner0_2") as "result0_2"
            FROM (SELECT
                  "values0_1" as "inner0_2",
                  *
                  FROM (SELECT
                        *
                        FROM (SELECT "column1" as "values0_1"
                              FROM
                              (VALUES
                               (CAST(TRUE AS bool)),
                               (CAST(FALSE AS bool))) as "V") as "T1") as "T1") as "T1"
            GROUP BY COALESCE(0)) as "T1") as "T1"

which errors with

ERROR:  column "values0_1" does not exist
LINE 2: ("values0_1") AND ("result0_2") as "anon"

There is a clear scoping violation in that query. When we had Applicative Aggregate with the traversal to group anything unaggregated this was OK, but then we found out you can't group arbitrary expressions (the type must have a notion equality).

I think we've reached the end of this exploration. Oh well!

how to use `groupBy`

I'm trying to write a query like

SELECT array_agg(foo) FROM bar GROUP BY baz

but I'm struggling to understand how to do it.

How should the groupBy combinator be used?

Documentation for binary operators has mismatching parameters

The documentation for intersect is:

Find the intersection of two queries, collapsing duplicates. intersect a b is the same as the SQL statement x INTERSECT b.

Note that it mentions the free variables a, b and x. It should only mention a and b.

Confusing error with `HList f (Column f X)`

I wrote

data BinAndLots f = BinAndLots
  { binId :: Column f BinId
  , lotIds :: HList f (Column f LotId)
  , binType :: Column f BinType
  } deriving (Generic, Rel8able)

And got:

src/CircuitHub/Persistence/OrderPlacementDetails.hs:162:24: error:
    • Couldn't match type ‘rel8-0.1.0.0:Rel8.Expr.Expr’
                     with ‘rel8-0.1.0.0:Rel8.Schema.Insert.Insert’
        arising from a functional dependency between:
          constraint ‘rel8-0.1.0.0:Rel8.Table.Table
                        rel8-0.1.0.0:Rel8.Schema.Insert.Insert
                        (rel8-0.1.0.0:Rel8.Expr.Expr LotId)’
            arising from the 'deriving' clause of a data type declaration
          instance ‘rel8-0.1.0.0:Rel8.Table.Table
                      rel8-0.1.0.0:Rel8.Expr.Expr (rel8-0.1.0.0:Rel8.Expr.Expr a)’
            at <no location info>
    • When deriving the instance for (Rel8able BinAndLots)
    |
162 |   } deriving (Generic, Rel8able)
    |                        ^^^^^^^^

src/CircuitHub/Persistence/OrderPlacementDetails.hs:162:24: error:
    • Couldn't match type ‘rel8-0.1.0.0:Rel8.Expr.Expr’
                     with ‘rel8-0.1.0.0:Rel8.Schema.Insert.Insert’
        arising from a functional dependency between:
          constraint ‘rel8-0.1.0.0:Rel8.Table.Table
                        rel8-0.1.0.0:Rel8.Schema.Insert.Insert
                        (rel8-0.1.0.0:Rel8.Expr.Expr LotId)’
            arising from the 'deriving' clause of a data type declaration
          instance ‘rel8-0.1.0.0:Rel8.Table.Table
                      rel8-0.1.0.0:Rel8.Expr.Expr (rel8-0.1.0.0:Rel8.Expr.Expr a)’
            at <no location info>
    • When deriving the instance for (Rel8able BinAndLots)
    |
162 |   } deriving (Generic, Rel8able)
    |                        ^^^^^^^^

src/CircuitHub/Persistence/OrderPlacementDetails.hs:162:24: error:
    • Couldn't match type ‘rel8-0.1.0.0:Rel8.Expr.Expr’
                     with ‘rel8-0.1.0.0:Rel8.Schema.Insert.Insert’
        arising from a functional dependency between:
          constraint ‘rel8-0.1.0.0:Rel8.Table.Table
                        rel8-0.1.0.0:Rel8.Schema.Insert.Insert
                        (rel8-0.1.0.0:Rel8.Expr.Expr LotId)’
            arising from the 'deriving' clause of a data type declaration
          instance ‘rel8-0.1.0.0:Rel8.Table.Table
                      rel8-0.1.0.0:Rel8.Expr.Expr (rel8-0.1.0.0:Rel8.Expr.Expr a)’
            at <no location info>
    • When deriving the instance for (Rel8able BinAndLots)
    |
162 |   } deriving (Generic, Rel8able)
    |                        ^^^^^^^^

src/CircuitHub/Persistence/OrderPlacementDetails.hs:162:24: error:
    • Couldn't match type ‘rel8-0.1.0.0:Rel8.Expr.Expr’
                     with ‘rel8-0.1.0.0:Rel8.Schema.Insert.Insert’
        arising from a functional dependency between:
          constraint ‘rel8-0.1.0.0:Rel8.Table.Table
                        rel8-0.1.0.0:Rel8.Schema.Insert.Insert
                        (rel8-0.1.0.0:Rel8.Expr.Expr LotId)’
            arising from the 'deriving' clause of a data type declaration
          instance ‘rel8-0.1.0.0:Rel8.Table.Table
                      rel8-0.1.0.0:Rel8.Expr.Expr (rel8-0.1.0.0:Rel8.Expr.Expr a)’
            at <no location info>
    • When deriving the instance for (Rel8able BinAndLots)
    |
162 |   } deriving (Generic, Rel8able)
    |                        ^^^^^^^^

It would be good if this either just worked, or gave a much more exact error message.

How to insert and return an auto-generated value

I have a typical sort of situation here where there's a table with an auto-incrementing ID (the "position" column in the schema below)...

data StripeCustomerQueue f = StripeCustomerQueue
  { stripeCustomerQueuePosition :: Column f StripeCustomerQueuePosition
  , stripeCustomerQueueCustomerId :: Column f StripeCustomerId
  , stripeCustomerQueueLiveMode :: Column f LiveMode
  }
  deriving stock (Generic)
  deriving anyclass (Rel8able)

... and I want to insert into the table, let the database set the position field to its default value, and return the generated value.

Insert
  { into = stripeCustomerQueueSchema
  , rows = one $ StripeCustomerQueue
      { stripeCustomerQueueLiveMode = lit mode
      , stripeCustomerQueueCustomerId = lit customerId
      , stripeCustomerQueuePosition = _
      }
  , onConflict = Abort
  , returning = Projection stripeCustomerQueuePosition
  }

What do I put in the hole above? Should I write unsafeLiteral "DEFAULT"? Or is there some other approach I'm missing?

A question about SQL injection

First of all, I wanted to thank you so much for making rel8 available 🎉

While trying to make myself familiar with the API, I saw many uses of the lit function. This made me wonder how rel8 was dealing with potential SQL injections, and digging into the internals I was left with the impression that the entire SQL generation is based on string concatenation, including the params themselves. Is this correct?

Normally in Postgres params are sent separately as part of the protocol, but I could not find that being done anywhere. I could not find any use of the prepared statement either. I guess my question is, is this library safe against SQL injection when passing text parameters as conditions in a query?

Rel8 generates poorly-typed sql

Given the following definitions:

newtype EdgeId = EdgeId
  { unEdgeId :: Int64
  }
  deriving newtype (Eq, Ord, Show, DBType, DBEq, DBOrd)

newtype DocId = DocId
  { unDocId :: Int64
  }
  deriving newtype (Eq, Ord, Show, DBType, DBEq, DBOrd)

data Discovery f = Discovery
  { d_docId :: Column f DocId
  , d_uri   :: Column f Text
  }
  deriving stock Generic
  deriving anyclass Rel8able

data Edges f = Edges
  { e_edgeId :: Column f EdgeId
  , e_src :: Column f DocId
  , e_dst :: Column f DocId
  }
  deriving stock Generic
  deriving anyclass Rel8able

the following Query (Discovery Expr):

do
  e <- do
    e <- each edgesSchema
    d <- each discoverySchema
    where_ $ e_src e ==. d_docId d &&. like (lit $ "%" <> t <> "%") (d_uri d)
    pure e
  d <- each discoverySchema
  where_ $ e_dst e ==. d_docId d
  pure d

produces the following sql:

SELECT
CAST("doc_id0_7" AS int8) as "d_docId",
CAST("uri1_7" AS text) as "d_uri"
FROM (SELECT
      *
      FROM (SELECT
            "id" as "id0_1",
            "src" as "src1_1",
            "dst" as "dst2_1"
            FROM "public"."edges" as "T1") as "T1",
           LATERAL
           (SELECT
            "doc_id" as "doc_id0_3",
            "uri" as "uri1_3"
            FROM "public"."discovery" as "T1") as "T2",
           LATERAL
           (SELECT
            "doc_id" as "doc_id0_7",
            "uri" as "uri1_7"
            FROM "public"."discovery" as "T1") as "T3"
      WHERE (("dst2_1") = ("doc_id0_7")) AND ((("src1_1") = ("doc_id0_3")) AND (CAST(("uri1_3") LIKE (CAST(E'%marginalrevolution.com%' AS text)) AS bool)))) as "T1"

which fails to run:

ERROR:  operator does not exist: text = bigint
LINE 21:       WHERE (("dst2_1") = ("doc_id0_7")) AND ((("src1_1") = ...
                                 ^
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.