I'm not sure why I cant get this working....
I have QuasiQuotes and OverloadedStrings at the top of my hs file, at the top of main.hs, maindevel.hs and also declared in my foo.cabal file.
The ERROR:
Couldn't match type ‘[Char]’ with ‘Text’
Expected type: Text
Actual type: String
In the second argument of ‘($)’, namely
‘renderHtml (GHC.Base.id (toHtml y))’
In the expression:
putStrLn $ renderHtml (GHC.Base.id (toHtml y))
Code:
module Widgets.MainWidgets where
{-# LANGUAGE GADTs #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings, TypeSynonymInstances, FlexibleInstances #-}
import Import
import Text.Hamlet (shamlet)
import Text.Blaze.Html.Renderer.String (renderHtml)
import Data.Char (toLower)
import Data.List (sort)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import ClassyPrelude
import Yesod
import Data.Time.Clock
import Data.Time.Calendar
import Data.Time.LocalTime
import Data.Time.Format
getCurrYear :: String
getCurrYear = formatTime defaultTimeLocale "%y" getCurrentTime
getYear :: IO ()
getYear = putStrLn $ renderHtml
[shamlet|#{y}|]
where y = getCurrYear
I also have this in my foo.cabal file:
extensions: TemplateHaskell
QuasiQuotes
OverloadedStrings
NoImplicitPrelude
CPP
MultiParamTypeClasses
TypeFamilies
GADTs
GeneralizedNewtypeDeriving
FlexibleContexts
EmptyDataDecls
NoMonomorphismRestriction
DeriveDataTypeable
ViewPatterns
TupleSections
RecordWildCards
TypeSynonymInstances
FlexibleInstances
DeriveGeneric
Any idea why I get the String/Text conversion error?
Thanks in advance!
Adrian
The putStrLn from ClassyPrelude takes a Text, not a String. The simplest solution would be to change the Renderer import to the Text version of the module.
Related
i´am getting error when i am uploading the file:
contains illegal pragma: {-# OPTIONS_GHC -Wno-incomplete-patterns #-}
why is it wrong?
I am programing an Tree in haskell:
{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
module Tree where
import Test.HUnit
import Data.Char
I've got the following application:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Main where
-- Scotty
import qualified Web.Scotty as S
import Network.Wai.Middleware.RequestLogger
import Network.Wai.Middleware.Static
import qualified Data.Text.Lazy as L
-- HTML rendering
import Text.Blaze.Html.Renderer.Text (renderHtml)
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as A
import Control.Monad.IO.Class
-- Database
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH
import Control.Monad.Trans.Resource (runResourceT, ResourceT)
import Control.Monad.Logger
-- URL generation
import System.Random
import Control.Monad (replicateM)
-- JSON
import Data.Map (fromList)
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Link
shortUrl L.Text
URLKey shortUrl
Primary shortUrl
longUrl L.Text
counter Int
deriving Show
|]
getURL :: L.Text -> IO (Maybe (Entity Link))
getURL shortId = runSqlite "links.db" $ do
maybeOriginal <- getBy $ URLKey shortId
pure maybeOriginal
-- I don't know what type to give this, that's probably the problem
addURL short long = runSqlite "links.db" $ do
insert $ Link short long
main :: IO ()
main = do
-- Connect to db and run migration
runSqlite "links.db" $ do runMigration migrateAll
S.scotty 3000 $ do
...
S.post "/shorten" $ do
-- Get URL
url <- S.param "url" :: S.ActionM L.Text
-- Generate a random short URL
randStr <- liftIO $ getRandStr 5
-- Add the urls to the database
liftIO $ addURL (L.pack randStr) url
-- Send JSON response with ID
S.json $ fromList [("id" :: String, randStr)]
I get the following error:
shortener> build (lib + exe)
Preprocessing library for shortener-0.1.0.0..
Building library for shortener-0.1.0.0..
Preprocessing executable 'shortener-exe' for shortener-0.1.0.0..
Building executable 'shortener-exe' for shortener-0.1.0.0..
[2 of 2] Compiling Main
/home/henry/haskell/shortener/app/Main.hs:86:5: error:
• Couldn't match type ‘PersistEntityBackend (Int -> Link)’
with ‘SqlBackend’
arising from a use of ‘insert’
• In the first argument of ‘($)’, namely ‘insert’
In a stmt of a 'do' block: insert $ Link short long
In the second argument of ‘($)’, namely
‘do insert $ Link short long’
|
86 | insert $ Link short long
| ^^^^^^
-- While building package shortener-0.1.0.0 (scroll up to its section to see the error) using:
/home/henry/.stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_3.4.1.0_ghc-9.0.2 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.4.1.0 build lib:shortener exe:shortener-exe --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
I'm not sure how to resolve this type error and I haven't been able to find anything of use online. There was this answer with a similar problem, but the given type signature and several variations of it did not work.
It turns out I forgot a field when inserting. I had
insert $ Link short long
I needed
insert $ Link short long 0
for the counter field of Link.
Unfortunately the error didn't make that at all clear.
Quite surprisingly, I'm trying to fix a compilation warning missing-export-lists by adding explicitly the elements imported one by one for a specific module, but somehow there is something magical that this module is implicitly exporting that I can't find....
is it possible to retrieve what is exported implicitly with ghc ?
Here is an example of my issue, Yesod is generating some code with TH and quasiquotes :
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Control.Monad.IO.Class (liftIO)
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
name String
age Int Maybe
deriving Show
|]
Then let's say we use that generated code that way :
people <- selectList
( [PersonAge >. 25, PersonAge <=. 30]
||. [PersonName /<-. ["Adam", "Bonny"]]
||. ([PersonAge ==. 50] ||. [PersonAge ==. 60])
)
[]
liftIO $ print people
Now I want to put share in a specific module and control precisely what I'm exporting from that code generated.
I don't know how it generates PersonName and PersonAge ! I don't how to specifically import these 2 types for example...
I'm new in Haskell. I woudl like to create simple crud rest api with scotty and persistence. I'm using sqlite with one table todo (title text, description text), I have some records in table. My point is to show all records on enpoint /todos in json format. When I print it I gets an error
• Couldn't match expected type ‘Data.Text.Internal.Lazy.Text’
with actual type ‘[Entity ToDo]’
• In the first argument of ‘text’, namely ‘(_ToDo)’
In a stmt of a 'do' block: text (_ToDo)
In the second argument of ‘($)’, namely
‘do _ToDo <- liftIO readToDo
text (_ToDo)’
|
69 | text(_ToDo)
| ^^^^^
My code:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Main where
import Data.Monoid ((<>))
import Web.Scotty
import qualified Web.Scotty as S
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH
import Data.Text (Text)
import Data.Time (UTCTime, getCurrentTime)
import qualified Data.Text as T
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Resource (runResourceT, ResourceT)
import Database.Persist.Sql
import Control.Monad (forM_)
import Control.Applicative
import Control.Monad.Logger
import Data.Aeson
import Data.Default.Class
import GHC.Generics
import Control.Monad.IO.Class (liftIO)
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
ToDo
title String
description String
deriving Show
|]
runDb :: SqlPersist (ResourceT (NoLoggingT IO)) a -> IO a
runDb = runNoLoggingT
. runResourceT
. withSqliteConn "todo.db"
. runSqlConn
instance ToJSON ToDo where
toJSON(ToDo title description) = object ["title" .= title, "description" .= description]
readToDo :: IO [Entity ToDo]
readToDo = (runDb $ selectList [] [LimitTo 10] )
routes :: ScottyM()
routes = do
S.get "/hello" $ do
text "hello world!"
S.get "/hello/:name" $ do
name <- param "name"
text ("hello" <> name <> "!")
S.get "/todos" $ do
_ToDo <- liftIO readToDo
text(_ToDo)
main = do
putStrLn "Starting server...."
scotty 7777 routes
How to correct this?
It looks like compiler accused you of having a bad conversion between the list of Entity ToDo-s and Data.Text.Lazy.
Please try to convert it by hand using pack function:
import Data.Text.Lazy (pack)
...
routes = do
S.get "/hello" $ do
text "hello world!"
S.get "/hello/:name" $ do
name <- param "name"
text ("hello" <> name <> "!")
S.get "/todos" $ do
_ToDo <- liftIO readToDo
text(pack . show $ _ToDo) -- explicit conversion
...
Is there any way to have as single TH function, define a type, and use the type, as well? Relevant code below. PersonPoly2 is being defined by makeRecordSplice and then being passed to makeAdaptorAndInstance (from Opalaye), which is also a TH function.
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Lib where
import Data.Profunctor.Product.TH (makeAdaptorAndInstance)
import Language.Haskell.TH
makeRecordSplice :: Q [Dec]
makeRecordSplice = [d|
data PersonPoly2 a b = Person2
{ id :: a
, name :: b
}
|]
makeRecordAndAdapter :: Q [Dec]
makeRecordAndAdapter = do
record <- makeRecordSplice
adapter <- makeAdaptorAndInstance "pPerson2" (mkName "PersonPoly2")
return $ record ++ adapter
-------------
/home/Projects/scratch/app/Main.hs:26:1: error:
‘PersonPoly2’ is not in scope at a reify
Failed, modules loaded: Lib.
The problem you are having is that makeRecordSplice needs to be in a different module than the one it is instantiated in. This Template-Haskell limitation ensures non-circular dependencies at compile time. It is an annoying limitation but not too difficult to go around. Here is one way you could do it:
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Data.Profunctor.Product.TH (makeAdaptorAndInstance)
import Language.Haskell.TH
import Lib (makeRecordSplice)
$(makeRecordSplice)
$(makeAdaptorAndInstance "pPerson2" (mkName "PersonPoly2"))
main :: IO ()
main = undefined
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Lib where
import Data.Profunctor.Product.TH (makeAdaptorAndInstance)
import Language.Haskell.TH
makeRecordSplice :: Q [Dec]
makeRecordSplice = [d|
data PersonPoly2 a b = Person2
{ id :: a
, name :: b
}
|]
You can obviously create an alias for makeAdaptorAndInstance "pPerson2" (mkName "PersonPoly2") and hide it in Lib, you just can't have a splice dependent on another one in the same module.
Hope this helps! :-)