[Haskell-cafe] trace output statements
Damien Mattei
damien.mattei at gmail.com
Wed Dec 26 22:24:53 UTC 2018
i'm learning fmap, but for now i want to convert the previous function:
getBD :: Connection -> String -> IO Float
getBD conn name = do
let qry_head_BD_Sidonie = "select `N° BD` from Coordonnées
where Nom = ?" :: Query
(bd_rows :: [Only Text]) <- query conn qry_head_BD_Sidonie
(Only (name::String))
let noBDtxt = fromOnly (Prelude.head bd_rows) :: Text
let noBDstr = Text.unpack noBDtxt :: String
let noBDfp = read $ noBDstr :: Float
return noBDfp
that works but fails in case of NULL in database,
i want the code to works also with NULL, detecting them with Nothing, and
short circuit them with Maybe or something else, so i change the function
definition to this type and here is the whole code:
getBD2 :: Connection -> String -> IO (Maybe Float)
getBD2 conn name = do
let qry_head_BD_Sidonie = "select `N° BD` from Coordonnées
where Nom = ?" :: Query
(bd_rows :: [Only (Maybe Text)]) <- query conn
qry_head_BD_Sidonie (Only (name::String))
let noBDtxt = if (isNothing (fromOnly (Prelude.head bd_rows)))
then (return Nothing)
else (fromOnly (Prelude.head bd_rows) :: Maybe
Text)
let noBDstr = Text.unpack noBDtxt :: Maybe String
let noBDfp = read $ noBDstr :: Maybe Float
return noBDfp
unfortunately it fails to compile, something is wrong here:
Prelude Data.Maybe> :load UpdateSidonie
[1 of 1] Compiling Main ( UpdateSidonie.hs, interpreted )
UpdateSidonie.hs:68:33: error:
• Couldn't match type ‘Text’ with ‘Maybe a’
Expected type: Maybe (Maybe a)
Actual type: Maybe Text
• In the expression:
(fromOnly (Prelude.head bd_rows) :: Maybe Text)
In the expression:
if (isNothing (fromOnly (Prelude.head bd_rows))) then
(return Nothing)
else
(fromOnly (Prelude.head bd_rows) :: Maybe Text)
In an equation for ‘noBDtxt’:
noBDtxt
= if (isNothing (fromOnly (Prelude.head bd_rows))) then
(return Nothing)
else
(fromOnly (Prelude.head bd_rows) :: Maybe Text)
• Relevant bindings include
noBDtxt :: Maybe (Maybe a) (bound at UpdateSidonie.hs:66:17)
|
68 | else (fromOnly (Prelude.head bd_rows) ::
Maybe Text)
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UpdateSidonie.hs:69:27: error:
• Couldn't match type ‘[Char]’ with ‘Maybe String’
Expected type: Maybe String
Actual type: String
• In the expression: unpack noBDtxt :: Maybe String
In an equation for ‘noBDstr’:
noBDstr = unpack noBDtxt :: Maybe String
In the expression:
do let qry_head_BD_Sidonie = ...
(bd_rows :: [Only (Maybe Text)]) <- query
conn qry_head_BD_Sidonie
(Only (name :: String))
let noBDtxt = ...
let noBDstr = ...
....
|
69 | let noBDstr = Text.unpack noBDtxt :: Maybe String
| ^^^^^^^^^^^^^^^^^^^
UpdateSidonie.hs:69:39: error:
• Couldn't match expected type ‘Text’
with actual type ‘Maybe (Maybe a0)’
• In the first argument of ‘unpack’, namely ‘noBDtxt’
In the expression: unpack noBDtxt :: Maybe String
In an equation for ‘noBDstr’:
noBDstr = unpack noBDtxt :: Maybe String
|
69 | let noBDstr = Text.unpack noBDtxt :: Maybe String
| ^^^^^^^
UpdateSidonie.hs:70:33: error:
• Couldn't match type ‘Maybe String’ with ‘[Char]’
Expected type: String
Actual type: Maybe String
• In the second argument of ‘($)’, namely ‘noBDstr’
In the expression: read $ noBDstr :: Maybe Float
In an equation for ‘noBDfp’: noBDfp = read $ noBDstr :: Maybe Float
|
70 | let noBDfp = read $ noBDstr :: Maybe Float
| ^^^^^^^
Failed, no modules loaded.
what is the solution? it will help me in my project and to understand
Haskell way of handling null objects.
Damien
On Tue, Dec 25, 2018 at 11:18 PM Ian Denhardt <ian at zenhack.net> wrote:
>
> (Adding the list back to Cc; you forgot to hit reply all)
>
> Quoting Damien Mattei (2018-12-25 16:57:04)
>
> > i get in trouble understanding what fmap was doing,
>
> fmap (for IO) just applies a function to the result of the action, so:
>
> fmap f action
>
> is equivalent to:
>
> do
> result <- action
> return (f result)
>
> > and why the same thing to do in main and in a function had so
> > different implementations...
>
> I suspect the modified version of the program has some differences that
> aren't strictly necessary just to factor out the relevant bits into
> their own definition; this *shouldn't* be major surgery. Hard for me to
> point out without having the two full examples handy.
>
> Quoting Damien Mattei (2018-12-25 16:57:04)
> > yes, i understand with your python example, it's like read on a web
> > page, IO are not a "cake" but IO are "a recipe for the cake"...
> > functions are pure in haskell, so they can not have side effects...
> > what put me some trouble is an answer 2 weeks ago, someone gave me
> > hints that lead to this solution for getDB:
> > getBD :: Connection -> String -> IO Float
> > getBD conn name = trace "Entering getBD" noBDfp
> > � where qry_head_BD_Sidonie = "select `N° BD` from Coordonnées where
> > Nom = ?" :: Query
> > � � � � � � � bd_rows :: IO [Only Text]
> > � � � � � � � bd_rows = query conn qry_head_BD_Sidonie (Only
> > (name::String))
> > � � � � � � � noBDtxt :: IO Text
> > � � � � � � � noBDtxt = trace "assigning noBDtxt" (fmap (fromOnly .
> > Prelude.head) bd_rows)
> > � � � � � � � noBDstr :: IO String
> > � � � � � � � noBDstr = trace "assigning noBDstr" (fmap Text.unpack
> > noBDtxt)
> > � � � � � � � noBDfp :: IO Float
> > � � � � � � � noBDfp = fmap read noBDstr
> > which was code different from the code in main,i get in trouble
> > understanding what fmap was doing , and why the same thing to do in
> > main and in a function had so different implementations...
> >
> > On Tue, Dec 25, 2018 at 10:19 PM Ian Denhardt <[1]ian at zenhack.net>
> > wrote:
> >
> > The correct type annotation for getDB3 should be:
> > � � getDB3 :: Connection -> String -> IO Float
> > Note the IO at the end. Functions in Haskell are just pure
> > computation;
> > they can't have side effects -- so a function returning a Float
> > can't
> > possibly talk to a database.
> > Instead, The type `IO a` represents a description of an action to
> > perform.� It's still just a value -- calling getDB3 doesn't *do*
> > anything. You can stitch these together using do-notation or
> > functions
> > like >>=, and when the program is run the action defined by 'main'
> > is
> > performed.
> > ---
> > An analogy: you could imagine instead of IO we could give up, and
> > write
> > code that computes a program in some other (imperative) programming
> > language) that we then hand off to an interpreter. For example, we
> > could
> > compute a python program that counts from 1 to 99 like so:
> > � � printNum :: Int -> String
> > � � printNum n = "print('" ++ show n ++ "')\n"
> > � � pythonProgram = concatMap printNum [1..99]
> > So we've defined a variable fullProgram that is a string with the
> > source
> > code to a python program like:
> > � � print('1')
> > � � print('2')
> > � � print('3')
> > � � ...
> > � � print('99')
> > ..but we haven't actually run it. To do that we'd have to pass the
> > string off to the python interpreter.
> > This is a good way to think about what IO is -- main is like our
> > pythonProgram above, in that it is a description of actions to
> > perform,
> > but *evaluating* it doesn't have any side effects -- it just
> > computes
> > the description. When you run a Haskell program, this is like taking
> > the description defined by Main and passing it off to an
> > interpreter.
> > ---
> > So your definition of getDB3 is a description of actions to perform
> > to
> > get a float from the database, but your type declaration says it's a
> > function that computes a float (without having to perform any
> > "actions").
> > This is a critical distinction that exists in Haskell but not most
> > other
> > languages.
> > Hope this helps,
> > -Ian
> > Quoting Damien Mattei (2018-12-25 15:07:35)
> > >� � yes i use do notation, but for example i have code that works
> > in main
> > >� � and not in a function!
> > >� � i print the code perheaps someone could help me:
> > >� � first the function, so you have the import list too:
> > >� � import Database.MySQL.Simple
> > >� � import Database.MySQL.Simple.QueryResults
> > >� � import Database.MySQL.Simple.Result
> > >� � import Database.MySQL.Simple.QueryParams
> > >� � import Database.MySQL.Simple.Param
> > >� � import Control.Monad
> > >� � import Data.Text as Text
> > >� � --import Data.Int as Int
> > >� � --import Data.List
> > >� � import Debug.Trace
> > >� � import Data.Maybe as Maybe
> > >� � -- this function will return th N°BD from Sidonie for a
> > given name
> > >� � -- note: names have been standardized between Sidonie and WDS
> > >� � getBD3 :: Connection -> String -> Float
> > >� � getBD3 conn name = do
> > >� � � � � � � � � � � � �� let
> > qry_head_BD_Sidonie = "select `N° BD` from
> > >� � Coordonnées where Nom = ?" :: Query
> > >� � � � � � � � � � � � �� (bd_rows ::
> > [Only Text]) <- query conn
> > >� � qry_head_BD_Sidonie (Only (name::String))
> > >� � � � � � � � � � � � �� let noBDtxt =
> > fromOnly (Prelude.head bd_rows) ::
> > >� � Text
> > >� � � � � � � � � � � � �� let noBDstr =
> > Text.unpack noBDtxt :: String
> > >� � � � � � � � � � � � �� let noBDfp =
> > read $ noBDstr :: Float
> > >� � � � � � � � � � � � �� return noBDfp
> > >� � with this function i have this error:
> > >� � Prelude> :load UpdateSidonie
> > >� � [1 of 1] Compiling Main� � � � � � � � �
> > � � �� ( UpdateSidonie.hs,
> > >� � interpreted )
> > >� � UpdateSidonie.hs:54:13: error:
> > >� � � � �� � Couldn't match expected type �Float�
> > with actual type �IO
> > >� � Float�
> > >� � � � �� � In a stmt of a 'do' block:
> > >� � � � � � � � �� (bd_rows :: [Only Text]) <-
> > query
> > >� � � � � � � � � � � � � � � � �
> > � � � � � � � � � � � � � � � � �
> > � � � �
> > >� � � �� conn qry_head_BD_Sidonie (Only (name :: String))
> > >� � � � � � �� In the expression:
> > >� � � � � � � � �� do let qry_head_BD_Sidonie =
> > ...
> > >� � � � � � � � � � � �� (bd_rows :: [Only
> > Text]) <- query
> > >� � � � � � � � � � � � � � � � �
> > � � � � � � � � � � � � � � � � �
> > � � � �
> > >� � � � � � �� conn qry_head_BD_Sidonie (Only (name ::
> > String))
> > >� � � � � � � � � � � �� let noBDtxt = ...
> > >� � � � � � � � � � � �� let noBDstr = ...
> > >� � � � � � � � � � � �� ....
> > >� � � � � � �� In an equation for �getBD3�:
> > >� � � � � � � � � � �� getBD3 conn name
> > >� � � � � � � � � � � � �� = do let
> > qry_head_BD_Sidonie = ...
> > >� � � � � � � � � � � � � � � � �
> > �� (bd_rows :: [Only Text]) <- query
> > >� � � � � � � � � � � � � � � � �
> > � � � � � � � � � � � � � � � � �
> > � � � �
> > >� � � � � � � � � � � � �� conn
> > qry_head_BD_Sidonie (Only (name :: String))
> > >� � � � � � � � � � � � � � � � �
> > �� let noBDtxt = ...
> > >� � � � � � � � � � � � � � � � �
> > �� ....
> > >� � � �� |
> > >� � 54 |� � � � � � � � � � � ��
> > (bd_rows :: [Only Text]) <- query conn
> > >� � qry_head_BD_Sidonie (Only (name::String))
> > >� � � �� |� � � � � � � � � � � �
> > >� �
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > ^^^
> > >� � ^^^^^^^^^
> > >� � Failed, no modules loaded.
> > >� � i do not understand the error complaining that i return an IO
> > >� � float,because i'm sure it's a float in noBDfp
> > >� � if i put the same lines of code in the main it works !!! :
> > >� � main :: IO ()
> > >� � main =
> > >� � �� do
> > >� � � � �� conn <- connect defaultConnectInfo
> > >� � � � � � �� { connectHost = "moita",
> > >� � � � � � � � �� connectUser = "mattei",
> > >� � � � � � � � �� connectPassword = "sidonie2",
> > >� � � � � � � � �� connectDatabase = "sidonie" }
> > >� � � let qry_head_BD_Sidonie = "select `N° BD` from
> > Coordonnées where
> > >� � Nom = ?" :: Query
> > >� � � (bd_rows :: [Only Text]) <- query conn
> > qry_head_BD_Sidonie (Only
> > >� � (name::String))
> > >� � putStr "bd_rows ="
> > >� � putStrLn $ show bd_rows
> > >� � � � �� let noBDtxt = fromOnly (Prelude.head bd_rows)
> > :: Text
> > >� � � � �� let noBDstr = Text.unpack noBDtxt :: String
> > >� � � � �� let noBDfp = read $ noBDstr :: Float
> > >� � � � �� putStr "noBDfp ="
> > >� � � � �� (putStrLn (show noBDfp))
> > >� � � close conn
> > >� � it works i have output like this:
> > >� � *Main> main
> > >� � bd_rows =[Only {fromOnly = "-04.3982"}]
> > >� � noBDtxt ="-04.3982"
> > >� � noBDfp =-4.3982
> > >� � noBDfp + 1 = -3.3982
> > >� � i'm well getting a float in noBDfp , i even can add 1 to it
> > :-) ( cool
> > >� � haskell...)
> > >� � but i'm just wanting to that in the function getDB3 but it
> > does not
> > >� � compile...
> > >� � ??????
> > >� � Damien
> > >
> > >� � On Sun, Dec 23, 2018 at 4:54 PM Tom Ellis
> > >� � <[1][2]tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk> wrote:
> > >
> > >� � � I think forgetting about monads and just using do-notation
> > will help
> > >� � � you.
> > >� � � On Sun, Dec 23, 2018 at 04:44:57PM +0100, Damien Mattei
> > wrote:
> > >� � � > i think learning Monads from scratch again will help me
> > >� � � >
> > >� � � > On Sun, Dec 23, 2018 at 4:11 PM Tom Ellis <
> > >� � � > [2][3]tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk>
> > wrote:
> > >� � � >
> > >� � � > > Yes, exactly!
> > >� � � > >
> > >� � � > > On Sun, Dec 23, 2018 at 02:08:57PM +0100, Damien
> > Mattei wrote:
> > >� � � > > > lazyness....?
> > >� � � > > >
> > >� � � > > > On Sun, Dec 23, 2018 at 8:40 AM Tom Ellis <
> > >� � � > > > [3][4]tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk>
> > wrote:
> > >� � � > > >
> > >� � � > > > > On Sat, Dec 22, 2018 at 09:52:18AM +0100, Damien
> > Mattei
> > >� � � wrote:
> > >� � � > > > > > i have inserted trace statement that output
> > variable
> > >� � � > > > > > ... i have strange behavior of output:
> > >� � � > > > >
> > >� � � > > > > Let's take a simpler example.�� Do you
> > understand why the
> > >� � � trace
> > >� � � > > statments
> > >� � � > > > > from this small program appear in the order that
> > they do?�
> > >� � � (And for
> > >� � � > > what
> > >� � � > > > > it's worth I really think you'll be better off
> > writing
> > >� � � programs using
> > >� � � > > do
> > >� � � > > > > notation).
> > >� � � > > > >
> > >� � � > > > >
> > >� � � > > > > % cat test.hs
> > >� � � > > > > import Debug.Trace
> > >� � � > > > >
> > >� � � > > > > result =
> > >� � � > > > >�� � let a = trace "evaluating a" 2
> > >� � � > > > >�� �� �� � b = trace "evaluating b" 10
> > >� � � > > > >�� �� �� � c = trace "evaluating c" (a +
> > b)
> > >� � � > > > >�� � in c
> > >� � � > > > > ~% ghci -e result test.hs
> > >� � � > > > > evaluating c
> > >� � � > > > > evaluating b
> > >� � � > > > > evaluating a
> > >� � � > > > > 12
> > >� � � > > _______________________________________________
> > >� � � > > Haskell-Cafe mailing list
> > >� � � > > To (un)subscribe, modify options or view archives go
> > to:
> > >� � � > >
> > [4][5]http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > >� � � > > Only members subscribed via the mailman list are
> > allowed to
> > >� � � post.
> > >� � � > _______________________________________________
> > >� � � > Haskell-Cafe mailing list
> > >� � � > To (un)subscribe, modify options or view archives go to:
> > >� � � >
> > [5][6]http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > >� � � > Only members subscribed via the mailman list are allowed
> > to post.
> > >� � � _______________________________________________
> > >� � � Haskell-Cafe mailing list
> > >� � � To (un)subscribe, modify options or view archives go to:
> > >� � �
> > [6][7]http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > >� � � Only members subscribed via the mailman list are allowed
> > to post.
> > >
> > > Verweise
> > >
> > >� � 1. mailto:[8]tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk
> > >� � 2. mailto:[9]tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk
> > >� � 3. mailto:[10]tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk
> > >� � 4.
> > [11]http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > >� � 5.
> > [12]http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > >� � 6.
> > [13]http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> >
> > Verweise
> >
> > 1. mailto:ian at zenhack.net
> > 2. mailto:tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk
> > 3. mailto:tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk
> > 4. mailto:tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk
> > 5. http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > 6. http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > 7. http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > 8. mailto:tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk
> > 9. mailto:tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk
> > 10. mailto:tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk
> > 11. http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > 12. http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > 13. http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20181226/9a916510/attachment.html>
More information about the Haskell-Cafe
mailing list