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