How to call a function as a top level declaration?


#1

Hi folks, I’m a beginner at Haskell trying to implement an API server. Below is the code I’m trying to compile and the question is at the end of this post.

Main.hs

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE DeriveGeneric #-}

module Main where

import Protolude
import qualified Data.Text as Text
import Network.Wai.Handler.Warp -- For `run` function.
import Servant
import Data.Aeson.Types -- `FromJSON`, `ToJSON`
import GHC.Generics -- `deriving Generic`
import Database.PostgreSQL.Typed
import DatabaseConnection (database)

-- Sets the database to use for checking types in application SQL queries.
useTPGDatabase database

type AccountApi = "account" :> ReqBody '[JSON] CreateAccountPayload :> Post '[JSON] Account

data CreateAccountPayload = CreateAccountPayload
  {
    email :: Text
  , password :: Text
  } deriving Generic -- What does `deriving Generic` do?

instance FromJSON CreateAccountPayload
instance ToJSON CreateAccountPayload

data Account = Account
  {
    id :: Integer
  , email :: Text
  } deriving Generic

instance FromJSON Account
instance ToJSON Account

accountHandler :: CreateAccountPayload -> Handler Account
accountHandler payload = return (Account 1 (email (payload :: CreateAccountPayload)))

server :: Server AccountApi
server = accountHandler

app :: Application
app = serve (Proxy :: Proxy AccountApi) server

main :: IO ()
main = run 4000 app

DatabaseConnection.hs

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE DataKinds #-}

module DatabaseConnection where

import Protolude
import Network
import Data.ByteString as ByteString
import Database.PostgreSQL.Typed
import Data.ByteString.UTF8 as BSU

database :: PGDatabase
database = defaultPGDatabase
  { pgDBHost = "localhost"
  , pgDBPort = PortNumber 5432
  , pgDBName = BSU.fromString "secretos_haskell"
  , pgDBUser = BSU.fromString "postgres"
  , pgDBPass = ByteString.empty
  , pgDBParams = []
  , pgDBDebug = True
  , pgDBLogMessage = print . PGError
  }

Compiler error:

Main.hs:19:1: error:
Parse error: module header, import declaration
or top-level declaration expected.
   |
19 | useTPGDatabase database
   | ^^^^^^^^^^^^^^^^^^^^^^^

My expectation is that since useTPGDatabase function is called after the import statements, then it should already be part of the top level block. The library that implements userTPGDatabase is https://github.com/dylex/postgresql-typed/tree/0.5.3.0.

Why does the compiler say that this is a parse error?


#2

I found the answer in IRC. I was missing the template haskell pragma declaration: {-# LANGUAGE TemplateHaskell #-}.