I'm trying to use Persist.sqlite to query my DB,..but in all the tutorials I have found so far is that first I have to migrate and insert data. Only after that came the select.
But what if I want to do only select over existing data? No migration and inserts before?
For example in the code below. What if I want to skip buildDb (currently that will not work)?
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies #-}
{-# LANGUAGE OverloadedStrings, GADTs, FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module DBio where
import Data.Text (Text)
import Database.Persist
import Database.Persist.Sqlite (runSqlite, runMigrationSilent)
import Database.Persist.TH (mkPersist, mkMigrate, persistLowerCase,
share, sqlSettings)
import Database.Persist.Sql (insert)
import Data.Conduit (($$))
import Data.Conduit.List as CL
import Control.Monad.IO.Class (liftIO)
share [mkPersist sqlSettings, mkMigrate "migrateTables"] [persistLowerCase|
Tutorial
value Double
url Text
school Bool
deriving Show
|]
run :: IO ()
run = runSqlite "../DB/mind.sqlite" $ do
buildDb
basic <- selectList [TutorialValue >. 0.0] []
liftIO $ print basic
buildDb = do
--runMigrationSilent migrateTables
insert $ Tutorial 2.22 "https://fpcomplete.com/school/basic-haskell-1" True
for example if I comment buildDb, after the table was once created i get following error:
No instance for (Control.Monad.IO.Class.MonadIO m0)
arising from a use of ‘insert’
The type variable ‘m0’ is ambiguous
Relevant bindings include
buildDb :: Control.Monad.Trans.Reader.ReaderT
persistent-2.2:Database.Persist.Sql.Types.SqlBackend
m0
(Key Tutorial)
(bound at DBio.hs:35:1)
Note: there are several potential instances:
instance Control.Monad.IO.Class.MonadIO m =>
Control.Monad.IO.Class.MonadIO
(conduit-1.2.5:Data.Conduit.Internal.Conduit.ConduitM i o m)
-- Defined in ‘conduit-1.2.5:Data.Conduit.Internal.Conduit’
instance Control.Monad.IO.Class.MonadIO m =>
Control.Monad.IO.Class.MonadIO
(conduit-1.2.5:Data.Conduit.Internal.Pipe.Pipe l i o u m)
-- Defined in ‘conduit-1.2.5:Data.Conduit.Internal.Pipe’
instance Control.Monad.IO.Class.MonadIO IO
-- Defined in ‘Control.Monad.IO.Class’
...plus 16 others
In the expression: insert
In a stmt of a 'do' block:
insert
$ Tutorial
2.22 "https://fpcomplete.com/school/basic-haskell-1" True
In the expression:
do { insert
$ Tutorial
2.22 "https://fpcomplete.com/school/basic-haskell-1" True }
I managed to get a working example. I guess that the problem above is with import modules.
{-# LANGUAGE OverloadedStrings, GADTs, TypeFamilies #-}
{-# LANGUAGE QuasiQuotes, TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses, GeneralizedNewtypeDeriving #-}
import Database.Persist ((>.), insertMany, Entity(..))
import Database.Persist.Sqlite (runSqlite,runMigration)
import qualified Database.Persist.TH as TH (share, mkPersist, sqlSettings,
mkMigrate, persistLowerCase)
import Control.Monad (mapM_)
import Database.Persist (selectList, entityVal)
import Database.Persist.Sqlite (runSqlite)
import Control.Monad.IO.Class (liftIO)
TH.share [TH.mkPersist TH.sqlSettings, TH.mkMigrate "migrateAll"] [TH.persistLowerCase|
MyRecord
value Int
deriving Show
|]
create :: IO ()
create = runSqlite "test.sqlite" $ do
let n = 10
runMigration migrateAll
insertMany $ map MyRecord [1..n]
return ()
get :: IO ()
get = runSqlite "test.sqlite" $ do
records <- selectList [MyRecordValue >. 9] []
liftIO $ print records
Related
I am trying to run the very first example in this tutorial:
Call JVM Methods from Haskell
module Main where
{-# LANGUAGE QuasiQuotes #-}
{-# OPTIONS_GHC -fplugin=Language.Java.Inline.Plugin #-}
import Language.Java (withJVM)
import Language.Java.Inline
main :: IO ()
main = withJVM [] [java| { System.out.println("Hello Java!"); } |]
and I get this error:
app\Main.hs:8:26: error: parse error on input `{'
|
8 | main = withJVM [] [java| { System.out.println("Hello Java!"); } |]
| ^
What am I doing wrong?
The {-# LANGUAGE … #-} and {-# OPTIONS_GHC … #-} pragmas need to be defined before the module Main declaration. Otherwise it will not enable the QuasiQuotes language extension, and thus not understand the quasiquotes used in the program.
If you install the inline-java and put the language pragmas before the module Main:
{-# LANGUAGE QuasiQuotes #-}
{-# OPTIONS_GHC -fplugin=Language.Java.Inline.Plugin #-}
module Main where
import Language.Java (withJVM)
import Language.Java.Inline
main :: IO ()
main = withJVM [] [java| { System.out.println("Hello Java!"); } |]
It should normally interpret the quasiquotes properly.
How can I use OmegaConf custom interpolation with Hydra?
Some background:
One can define a custom interpolation for square root:
from omegaconf import OmegaConf
import math
OmegaConf.register_resolver("sqrt", lambda x: math.sqrt(float(x)))
And use it with this config.yaml:
foo: ${sqrt:9}
Loading and printing foo:
cfg = OmegaConf.load('config.yaml')
print(cfg.foo)
Outputs 3.0
When trying this with Hydra:
import hydra
#hydra.main(config_path="config.yaml")
def main(cfg):
print(cfg.foo)
if __name__ == "__main__":
main()
I get the following error:
Unsupported interpolation type sqrt
full_key: foo
reference_type=Optional[Dict[Any, Any]]
object_type=dict
How can I register my resolver when using Hydra?
You can register your custom resolver ahead of time:
config.yaml:
foo: ${sqrt:9}
main.py:
from omegaconf import OmegaConf
import math
import hydra
OmegaConf.register_new_resolver("sqrt", lambda x: math.sqrt(float(x)))
#hydra.main(config_path=".", config_name="config")
def main(cfg):
print(cfg.foo)
if __name__ == "__main__":
main()
This will print 3.0.
This approach will work just as well with the Compose API. The evaluation of the custom resolver is happening when you access the node (lazily).
You just need to register the resolver before you access it.
Is there any order to be maintained while placing functions one another?
I just tried the code on the online compiler provided by purescript.org itself
"http://try.purescript.org"
module Main where
import Prelude
import Data.List
import Data.Array ((..))
import Data.Traversable (traverse)
import Control.Monad.Eff.Console(log)
import TryPureScript(render,withConsole)
main = render =<< withConsole do
log $ "Hello world"
traverse (\x -> log $ show $ x) (1..10)
log $ "Hello world"
The code is compiling absolutely fine when the last log function is removed or when the traverse function is removed.But its not working while they are placed in such an order.These two(log & traverse) functions are working perfectly individually but not together.Help me to get out of this issue.
I think the error message already give you a hint, you can fix by
_ <- traverse (\x -> log $ show $ x) (1..10)
-- or
void $ traverse (\x -> log $ show $ x) (1..10)
I'm trying really hard to understand how to use lenses and wreq and its turning out to really slow me down.
The error seems to be claiming there's some mismatched type here. I'm not sure exactly how to handle that though. I'm still fairly new to haskell and these lenses are pretty confusing. However, wreq seems to be cleaner, which is why I chose to use it. Can anyone help me understand what the error is, and how to fix it? I seem to run into alot of these type errors. I am aware that Maybe TestInfo won't be returned by my code at the moment. That's ok. That error know how to handle. This error however, I don't.
Here is my code:
Module TestInformation:
{-# LANGUAGE OverloadedStrings #-}
module TestInformation where
import Auth
import Network.Wreq
import Control.Lens
import Data.Aeson
import Data.Aeson.Lens (_String)
type TestNumber = String
data TestInfo = TestInfo {
TestId :: Int,
TestName :: String,
}
instance FromJSON TestInfo
getTestInfo :: Key -> TestNumber -> Maybe TestInfo
getTestInfo key test =
decode (res ^. responseBody . _String)
where opts = defaults & auth ?~ oauth2Bearer key
res = getWith opts ("http://testsite.com/v1/tests/" ++ test)
Module Auth:
module Auth where
import qualified Data.ByteString as B
type Key = B.ByteString
The error:
GHCi, version 7.10.1: http://www.haskell.org/ghc/ :? for help
[1 of 2] Compiling Auth ( Auth.hs, interpreted )
[2 of 2] Compiling TestInformation ( TestInformation.hs, interpreted )
TestInformation.hs:36:18:
Couldn't match type ‘Response body10’
with ‘IO (Response Data.ByteString.Lazy.Internal.ByteString)’
Expected type: (body10
-> Const Data.ByteString.Lazy.Internal.ByteString body10)
-> IO (Response Data.ByteString.Lazy.Internal.ByteString)
-> Const
Data.ByteString.Lazy.Internal.ByteString
(IO (Response Data.ByteString.Lazy.Internal.ByteString))
Actual type: (body10
-> Const Data.ByteString.Lazy.Internal.ByteString body10)
-> Response body10
-> Const Data.ByteString.Lazy.Internal.ByteString (Response body10)
In the first argument of ‘(.)’, namely ‘responseBody’
In the second argument of ‘(^.)’, namely ‘responseBody . _String’
TestInformation.hs:36:33:
Couldn't match type ‘Data.ByteString.Lazy.Internal.ByteString’
with ‘Data.Text.Internal.Text’
Expected type: (Data.ByteString.Lazy.Internal.ByteString
-> Const
Data.ByteString.Lazy.Internal.ByteString
Data.ByteString.Lazy.Internal.ByteString)
-> body10 -> Const Data.ByteString.Lazy.Internal.ByteString body10
Actual type: (Data.Text.Internal.Text
-> Const
Data.ByteString.Lazy.Internal.ByteString Data.Text.Internal.Text)
-> body10 -> Const Data.ByteString.Lazy.Internal.ByteString body10
In the second argument of ‘(.)’, namely ‘_String’
In the second argument of ‘(^.)’, namely ‘responseBody . _String’
Failed, modules loaded: Auth.
Leaving GHCi.
This type checks for me:
getTestInfo :: Key -> TestNumber -> IO (Maybe TestInfo)
getTestInfo key test = do
res <- getWith opts ("http://testsite.com/v1/tests/" ++ test)
return $ decode (res ^. responseBody)
where opts = defaults & auth ?~ oauth2Bearer key
getWith is an IO action, so to get its return value you need to use the monadic binding operator <-.
Full program: http://lpaste.net/133443 http://lpaste.net/133498
Is there a way to make https calls with the Network.Browser package.
I'm not seeing it in the documentation on Hackage.
If there isn't a way to do it with browse is there another way to fetch https pages?
My current test code is
import Network.HTTP
import Network.URI (parseURI)
import Network.HTTP.Proxy
import Data.Maybe (fromJust)
import Control.Applicative ((<$>))
import Network.Browser
retrieveUrl :: String -> IO String
retrieveUrl url = do
rsp <- browse $ request (Request (fromJust uri) POST [] "Body")
return $ snd (rspBody <$> rsp)
where uri = parseURI url
I've been running nc -l -p 8000 and watching the output.
I see that it doesn't encrypt it when I do retrieveUrl https://localhost:8000
Also when I try a real https site I get:
Network.Browser.request: Error raised ErrorClosed
*** Exception: user error (Network.Browser.request: Error raised ErrorClosed)
Edit: Network.Curl solution (For doing a SOAP call)
import Network.Curl (curlGetString)
import Network.Curl.Opts
soapHeader s = CurlHttpHeaders ["Content-Type: text/xml", "SOAPAction: " ++ s]
proxy = CurlProxy "proxy.foo.org"
envelope = "myRequestEnvelope.xml"
headers = readFile envelope >>= (\x -> return [ soapHeader "myAction"
, proxy
, CurlPost True
, CurlPostFields [x]])
main = headers >>= curlGetString "https://service.endpoint"
An alternative and perhaps more "haskelly" solution as Travis Brown put it with http-conduit:
To just fetch https pages:
import Network.HTTP.Conduit
import qualified Data.ByteString.Lazy as L
main = simpleHttp "https://www.noisebridge.net/wiki/Noisebridge" >>= L.putStr
The below shows how to pass urlencode parameters.
{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Conduit
import qualified Data.ByteString.Lazy as L
main = do
initReq <- parseUrl "https://www.googleapis.com/urlshortener/v1/url"
let req' = initReq { secure = True } -- Turn on https
let req = (flip urlEncodedBody) req' $
[ ("longUrl", "http://www.google.com/")
-- ,
]
response <- withManager $ httpLbs req
L.putStr $ responseBody response
You can also set the method, content-type, and request body manually. The api is the same as in http-enumerator a good example is: https://stackoverflow.com/a/5614946
I've wondered about this in the past and have always ended up just using the libcurl bindings. It would be nice to have a more Haskelly solution, but Network.Curl is very convenient.
If all you want to do is fetch a page, Network.HTTP.Wget is the most simple way. Exhibit a:
import Network.HTTP.Wget
main = putStrLn =<< wget "https://www.google.com" [] []