
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