
hello again, another question with Haskell, again with my database but that is again related to Monads: i have this code in main: rows <- query_ conn "SELECT Nom,distance FROM AngularDistance WHERE distance > 0.000278" let lg = Prelude.length rows let tst = if lg > 1 then "some" else "one or zero" it compiles and i assume it works, and i have a new (for those that have follow my previous posts) function like this one: -- this function will return the list of N°BD from WDS for a given name -- note: there could be multiple result for a given name in WDS due to components getBD_WDS :: Connection -> String -> IO Float getBD_WDS conn name = trace "Entering getBD_WDS" noBDfp where qry_head = "select DNUM from WDS where DISC = ?" :: Query bd_rows :: IO [Only Text] bd_rows = query conn qry_head (Only (name::String)) lg = fmap Prelude.length bd_rows -- tst = if (fmap lg) > 1 then "some" else "one or zero" noBDtxt :: IO Text -- noBDtxt = trace "lg " (fmap (fromOnly . Prelude.head) bd_rows) noBDtxt = (fmap (fromOnly . Prelude.head) bd_rows) -- noBDstr :: String -- noBDstr = Text.unpack noBDtxt noBDstr :: IO String noBDstr = fmap Text.unpack noBDtxt -- noBDfp = read $ noBDstr :: Float noBDfp :: IO Float noBDfp = trace "Exiting getBD" (fmap read noBDstr) the problem is that first i noticed that in a function to make working the same code than in Main i had to had almost always fmap before the line, i admit ,even if i'm teacher in functional programming in Scheme at University, i begin in Haskell and i don't always understand what i'm using, i try to learn it by instinct even if sometimes i read pages about Functor and Monads i have no time to get in the Mathematics theoretical knowledge behind Haskell, i try to learn by getting some solutions in Haskell-cafe and it works, i know now a lot more about Haskell than 2 weeks ago,so.... if someon could explain me a few more about fmap or just give what i must place in my function instead of let lg = Prelude.length rows let tst = if lg > 1 then "some" else "one or zero" i replace this in the function by: lg = fmap Prelude.length bd_rows OK for compilation, but then tst = if lg > 1 then "some" else "one or zero" does not compile: *Main> :load UpdateSidonie [1 of 1] Compiling Main ( UpdateSidonie.hs, interpreted ) UpdateSidonie.hs:80:18: error: • No instance for (Ord (IO Int)) arising from a use of ‘>’ • In the expression: lg > 1 In the expression: if lg > 1 then "some" else "one or zero" In an equation for ‘tst’: tst = if lg > 1 then "some" else "one or zero" | 80 | tst = if lg > 1 then "some" else "one or zero" | ^^^^^^ UpdateSidonie.hs:80:23: error: • No instance for (Num (IO Int)) arising from the literal ‘1’ • In the second argument of ‘(>)’, namely ‘1’ In the expression: lg > 1 In the expression: if lg > 1 then "some" else "one or zero" | 80 | tst = if lg > 1 then "some" else "one or zero" | ^ Failed, no modules loaded. and even the "fmap miraculous function" as i call it no more works: tst = if (fmap lg) > 1 then "some" else "one or zero" Prelude> :load UpdateSidonie [1 of 1] Compiling Main ( UpdateSidonie.hs, interpreted ) UpdateSidonie.hs:80:24: error: • Couldn't match expected type ‘a0 -> b0’ with actual type ‘IO Int’ • In the first argument of ‘fmap’, namely ‘lg’ In the first argument of ‘(>)’, namely ‘(fmap lg)’ In the expression: (fmap lg) > 1 | 80 | tst = if (fmap lg) > 1 then "some" else "one or zero" | ^^ Failed, no modules loaded. a solution to this proble i think , will help me a lot, i sticked with problems in haskell i would have already solved in Scheme or Python, that's really discouraging me of using Haskell, i'm obstinating myself because i really think it's a great language that push the programming to high levels of abstractions but for now it's a bit a nightmare, i must admit it... -- Damien.Mattei@unice.fr, Damien.Mattei@oca.eu, UNS / OCA / CNRS

On Fri, Dec 14, 2018 at 11:49:45AM +0100, Damien Mattei wrote:
another question with Haskell, again with my database but that is again related to Monads:
Damien, it's very hard to read your posts because they consist of snippets of code interspersed with commentary. You'll probably get much better responses if you post single, very small, well-formatted examples of sample code. Anyway, the ultimate answer to your query is "use do-notation". Your getBS_WDS would be clearer written something like: ``` getBD_WDS :: Connection -> String -> IO Float getBD_WDS conn name = do let qry_head = "select DNUM from WDS where DISC = ?" :: Query bd_rows <- query conn qry_head (Only name) let noBDtxt :: Text noBDtxt = fromOnly (Prelude.head bd_rows) noBDstr :: String noBDstr = Text.unpack noBDtxt noBDfp :: Float noBDfp = read noBDstr return noBDfp ``` Tom

On Fri, Dec 14, 2018 at 11:22:38AM +0000, Tom Ellis wrote:
On Fri, Dec 14, 2018 at 11:49:45AM +0100, Damien Mattei wrote:
another question with Haskell, again with my database but that is again related to Monads:
Damien, it's very hard to read your posts because they consist of snippets of code interspersed with commentary. You'll probably get much better responses if you post single, very small, well-formatted examples of sample code.
Anyway, the ultimate answer to your query is "use do-notation". Your getBS_WDS would be clearer written something like:
Ah, I see now why you were determined to use `fmap`. Seph recommended it to you I would avoid using do-notation at all until you’re a bit more comfortable with how monadic computations work, and how Haskell handles IO. To someone used to imperative programming, it can be more confusing that helpful, as it allows you to write something that looks and feels a lot like imperative code but differs from it in crucial ways. Get comfortable with using the monadic operators >> and >>= directly, and only then switch back to do-notation. Or don’t—personally I prefer not to use do-notation at all. -- Seph Shewell Brockway https://mail.haskell.org/pipermail/haskell-cafe/2018-December/130367.html I have to say I have completely the opposite position to Seph. If you try to write code in IO as a beginner without using do-notation you are in for a world of pain. Damien, I would suggest you write (very) small practice programs using both Seph's advice and mine and see which style you prefer and which helps you learn Haskell quicker. Tom

On Fri, Dec 14, 2018 at 11:22:38AM +0000, Tom Ellis wrote:
On Fri, Dec 14, 2018 at 11:49:45AM +0100, Damien Mattei wrote:
another question with Haskell, again with my database but that is again related to Monads:
Damien, it's very hard to read your posts because they consist of snippets of code interspersed with commentary. You'll probably get much better responses if you post single, very small, well-formatted examples of sample code.
Anyway, the ultimate answer to your query is "use do-notation". Your getBS_WDS would be clearer written something like:
And ultimately I think you wanted to do something with lg and tst: ``` getBD_WDS :: Connection -> String -> IO Float getBD_WDS conn name = do let qry_head = "select DNUM from WDS where DISC = ?" :: Query bd_rows <- query conn qry_head (Only name) let lg = Prelude.length bd_rows putStrLn (if lg > 1 then "some" else "one or zero") let noBDtxt :: Text noBDtxt = fromOnly (Prelude.head bd_rows) noBDstr :: String noBDstr = Text.unpack noBDtxt noBDfp :: Float noBDfp = read noBDstr return noBDfp ```

ok Elis i tried again, first ,as i am familiar with λ expressions i can use both do syntactic sugar or the other form with λ. so itried you code,surpringly it compiles but when i launch it the function can not print somethin on screen, i assume it is because function are pure in haskell, nor with putStrln or Debug.trace: getBD_WDS :: Connection -> String -> IO Float getBD_WDS conn name = do let qry_head = "select DNUM from WDS where DISC = ?" :: Query bd_rows <- query conn qry_head (Only name) let lg = Prelude.length bd_rows -- putStrLn (if lg > 1 then "some" else "one or zero") let tst = trace (if lg > 1 then "some" else "one or zero") (if lg > 1 then "some" else "one or zero") -- let noBDtxt :: Text let noBDtxt = fromOnly (Prelude.head bd_rows) -- noBDstr :: String let noBDstr = Text.unpack noBDtxt -- noBDfp :: Float let noBDfp = read noBDstr return noBDfp in fact due to lazy evaluation i'm not sure it compiles all the code because a more simple example give compilation errors: getLstBD_WDS :: Connection -> String -> IO Int getLstBD_WDS conn name = do let qry_head = "select DNUM from WDS where DISC = ?" :: Query bd_rows <- query conn qry_head (Only name) let lg = Prelude.length bd_rows return lg Prelude> :load UpdateSidonie [1 of 1] Compiling Main ( UpdateSidonie.hs, interpreted ) UpdateSidonie.hs:123:14: error: • Ambiguous type variable ‘r0’ arising from a use of ‘query’ prevents the constraint ‘(QueryResults r0)’ from being solved. Probable fix: use a type annotation to specify what ‘r0’ should be. These potential instances exist: instance Result a => QueryResults (Only a) -- Defined in ‘Database.MySQL.Simple.QueryResults’ instance (Result a, Result b) => QueryResults (a, b) -- Defined in ‘Database.MySQL.Simple.QueryResults’ instance (Result a, Result b, Result c) => QueryResults (a, b, c) -- Defined in ‘Database.MySQL.Simple.QueryResults’ ...plus 21 others (use -fprint-potential-instances to see them all) • In a stmt of a 'do' block: bd_rows <- query conn qry_head (Only name) In the expression: do let qry_head = ... bd_rows <- query conn qry_head (Only name) let lg = Prelude.length bd_rows return lg In an equation for ‘getLstBD_WDS’: getLstBD_WDS conn name = do let qry_head = ... bd_rows <- query conn qry_head (Only name) let lg = ... .... | 123 | bd_rows <- query conn qry_head (Only name) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Failed, no modules loaded. Le 14/12/2018 12:45, Tom Ellis a écrit :
On Fri, Dec 14, 2018 at 11:22:38AM +0000, Tom Ellis wrote:
On Fri, Dec 14, 2018 at 11:49:45AM +0100, Damien Mattei wrote:
another question with Haskell, again with my database but that is again related to Monads:
Damien, it's very hard to read your posts because they consist of snippets of code interspersed with commentary. You'll probably get much better responses if you post single, very small, well-formatted examples of sample code.
Anyway, the ultimate answer to your query is "use do-notation". Your getBS_WDS would be clearer written something like:
And ultimately I think you wanted to do something with lg and tst:
``` getBD_WDS :: Connection -> String -> IO Float getBD_WDS conn name = do let qry_head = "select DNUM from WDS where DISC = ?" :: Query
bd_rows <- query conn qry_head (Only name)
let lg = Prelude.length bd_rows
putStrLn (if lg > 1 then "some" else "one or zero")
let noBDtxt :: Text noBDtxt = fromOnly (Prelude.head bd_rows)
noBDstr :: String noBDstr = Text.unpack noBDtxt
noBDfp :: Float noBDfp = read noBDstr
return noBDfp ```
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- Damien.Mattei@unice.fr, Damien.Mattei@oca.eu, UNS / OCA / CNRS

On Fri, Dec 14, 2018 at 9:36 AM Damien Mattei
in fact due to lazy evaluation i'm not sure it compiles all the code because a more simple example give compilation errors:
Er? Lazy evaluation has nothing to do with what gets compiled; the only way the compiler doesn't "compile all the code" is if you are using the CPP extension and #ifdef etc. to exclude some. -- brandon s allbery kf8nh allbery.b@gmail.com

yes i must admit but things are more and more weirds.... non i do not know why the first of those lines is OK and the other not for compilation: bd_rows <- query conn qry_head (Only (name::String)) bd_rows_WDS <- query conn qry_head_WDS (Only (name::String)) note:if i swap the order it always the line with qry_head_WDS that fails: *Main> :load UpdateSidonie [1 of 1] Compiling Main ( UpdateSidonie.hs, interpreted ) UpdateSidonie.hs:202:20: error: • Ambiguous type variable ‘r0’ arising from a use of ‘query’ prevents the constraint ‘(QueryResults r0)’ from being solved. Probable fix: use a type annotation to specify what ‘r0’ should be. These potential instances exist: instance Result a => QueryResults (Only a) -- Defined in ‘Database.MySQL.Simple.QueryResults’ instance (Result a, Result b) => QueryResults (a, b) -- Defined in ‘Database.MySQL.Simple.QueryResults’ instance (Result a, Result b, Result c) => QueryResults (a, b, c) -- Defined in ‘Database.MySQL.Simple.QueryResults’ ...plus 21 others (use -fprint-potential-instances to see them all) • In a stmt of a 'do' block: bd_rows_WDS <- query conn qry_head_WDS (Only (name :: String)) In the expression: do conn <- connect defaultConnectInfo {connectHost = "moita", connectUser = "mattei", connectPassword = "sidonie2", connectDatabase = "sidonie"} rows <- query_ conn "SELECT Nom,distance FROM AngularDistance WHERE distance > 0.000278" let lg = Prelude.length rows let tst = ... .... In an equation for ‘main’: main = do conn <- connect defaultConnectInfo {connectHost = "moita", connectUser = "mattei", connectPassword = "sidonie2", connectDatabase = "sidonie"} rows <- query_ conn "SELECT Nom,distance FROM AngularDistance WHERE distance > 0.000278" let lg = ... .... | 202 | bd_rows_WDS <- query conn qry_head_WDS (Only (name::String)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Failed, no modules loaded. for the curious i attach the whole code (UpdateSidonie.hs), i'm really tired of Haskell.... i hope with the file it will be more easy to help me... Le 14/12/2018 16:14, Brandon Allbery a écrit :
On Fri, Dec 14, 2018 at 9:36 AM Damien Mattei
mailto:mattei@oca.eu> wrote: in fact due to lazy evaluation i'm not sure it compiles all the code because a more simple example give compilation errors:
Er? Lazy evaluation has nothing to do with what gets compiled; the only way the compiler doesn't "compile all the code" is if you are using the CPP extension and #ifdef etc. to exclude some.
-- brandon s allbery kf8nh allbery.b@gmail.com mailto:allbery.b@gmail.com
-- Damien.Mattei@unice.fr, Damien.Mattei@oca.eu, UNS / OCA / CNRS

If you want to print something out use putStrLn. It will work. On Fri, Dec 14, 2018 at 03:36:03PM +0100, Damien Mattei wrote:
so itried you code,surpringly it compiles but when i launch it the function can not print somethin on screen, i assume it is because function are pure in haskell, nor with putStrln or Debug.trace:
getBD_WDS :: Connection -> String -> IO Float getBD_WDS conn name = do let qry_head = "select DNUM from WDS where DISC = ?" :: Query
bd_rows <- query conn qry_head (Only name)
let lg = Prelude.length bd_rows
-- putStrLn (if lg > 1 then "some" else "one or zero") let tst = trace (if lg > 1 then "some" else "one or zero") (if lg > 1 then "some" else "one or zero")
-- let noBDtxt :: Text let noBDtxt = fromOnly (Prelude.head bd_rows)
-- noBDstr :: String let noBDstr = Text.unpack noBDtxt
-- noBDfp :: Float let noBDfp = read noBDstr
return noBDfp
participants (3)
-
Brandon Allbery
-
Damien Mattei
-
Tom Ellis