<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jan 7, 2019 at 5:55 PM Jake <<a href="mailto:jake.waksbaum@gmail.com">jake.waksbaum@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="auto">Like Josh mentioned, <a href="http://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Applicative.html#v:liftA2" target="_blank">Applicative Functors</a> are what you want. There are two idiomatic ways to do it:</div><div dir="auto"><ul><li>You can just use liftA2, which has type (a -> b -> c) -> f a -> f b -> f c. That means it lifts a binary function to some applicative functor like maybe, so liftA2 (++) :: Maybe String -> Maybe String -> Maybe String<br></li><li>In general, for any arity f that you want to lift to an applicative functor. So you have a function g that takes a bunch of arguments of types a, b, c, ... and gives you back an r and you want to get a function that takes an f a, f b, f c, ... and gives you back an f r, you can write f <$> a <*> b <*> c ... This works because <$> let's you apply g to type f a and gives you an f (b -> c ..) -> f r, and <*> basically let's you take the function back out of the f and apply it to the b to get a f (c ..) -> f r and so on. <b>tl;dr</b> you can write (++) <$> s1 <*> s2. In fact, liftA2 must satisfy the equation <span style="background-color:rgb(255,255,255)"><code style="color:rgb(0,0,0);font-size:13px;margin:0px;padding:0px;line-height:16.12px"><a href="http://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Applicative.html#v:liftA2" title="Control.Applicative" style="margin:0px;padding:0px;text-decoration-line:none;color:rgb(171,105,84)" target="_blank">liftA2</a></code><span style="color:rgb(0,0,0);font-size:13px"> f x y = f </span><code style="color:rgb(0,0,0);font-size:13px;margin:0px;padding:0px;line-height:16.12px"><$></code><span style="color:rgb(0,0,0);font-size:13px"> x </span><code style="color:rgb(0,0,0);font-size:13px;margin:0px;padding:0px;line-height:16.12px"><a href="http://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Applicative.html#v:-60--42--62-" title="Control.Applicative" style="margin:0px;padding:0px;text-decoration-line:none;color:rgb(171,105,84)" target="_blank"><*></a></code><span style="color:rgb(0,0,0);font-size:13px"> y </span></span>so these are the same thing.</li></ul></div><div class="gmail_quote"><div dir="ltr">בתאריך יום ב׳, 7 בינו׳ 2019, 17:41, מאת ☂Josh Chia (謝任中) <<a href="mailto:joshchia@gmail.com" target="_blank">joshchia@gmail.com</a>>:<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">Firstly, because "resBDwords :: Maybe String", not "resBDwords :: String", "lgBDwords = length resBDwords" probably is not what you want -- it does not give you the number of words in the String that may be in there.<div><br></div><div>Second, for the problem you asked about, you could just use a function that takes a String and do it "the hard way" like you said, using case outside before calling the function. Another way is to use an applicative functor to allow you to have a "Maybe String -> Maybe String -> Maybe String". This is used once for each "++" that you want to do.</div><div><br></div><div>I don't know exactly what you need to accomplish but I would just write a function "f :: String -> Maybe String" implementing the logic you listed in the second code snippet but operating on String instead of "Maybe String" and do "join . fmap f $ resBDwords".</div></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Jan 8, 2019 at 12:13 AM Damien Mattei <<a href="mailto:mattei@oca.eu" rel="noreferrer" target="_blank">mattei@oca.eu</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">hello,<br>
<br>
i have a variable resBDwords of type ( i expect) Maybe [String], for<br>
info it is integer and fractional part of a number<br>
<br>
example looks like this :<br>
resBDwords =Just ["-04","3982"]<br>
<br>
i want to concatanate "-04" and "3982" in the example, i begin to<br>
understand fmap to use the functor hidden in the Maybe ,it worked<br>
previously:<br>
<br>
let resBDstr = fmap Tx.unpack resBDtxt<br>
    putStr "resBDstr ="<br>
    putStrLn (show resBDtxt)<br>
<br>
    let resBDwords = fmap words resBDstr<br>
    putStr "resBDwords ="<br>
    putStrLn (show resBDwords)<br>
<br>
which gives:<br>
<br>
resBDtxt ="-04 3982"<br>
resBDstr =Just "-04 3982"<br>
<br>
<br>
just after in my code i have this to concatanate the two strings f and s<br>
that are the first and second element of the array:<br>
<br>
<br>
putStr "resBDwords ="<br>
    putStrLn (show resBDwords)<br>
<br>
    let lgBDwords = length resBDwords<br>
<br>
    let resBDstrFloat = if lgBDwords == 0<br>
                           then trace "WARNING: BD contains no words"<br>
Nothing<br>
                           else<br>
                               if lgBDwords == 1<br>
                                  then trace "WARNING: BD contains only<br>
one word" fmap head resBDwords<br>
                                  else let f = fmap head resBDwords<br>
                                           s = fmap (head . tail) resBDwords<br>
                                       in f ++ "." ++ S<br>
<br>
but i do not know how to concatanate the Maybe String in an elegant way,<br>
using somethin like fmap variable which have handled Nothing (from<br>
Maybe) automatically i need the counter part for multipe variable<br>
<br>
i do not want to do it using the hard way with case... of Just x -><br>
nothing .........<br>
<br>
i got this error :<br>
*Main> :load UpdateSidonie<br>
[1 of 1] Compiling Main             ( UpdateSidonie.hs, interpreted )<br>
<br>
UpdateSidonie.hs:339:43: error:<br>
    • Couldn't match expected type ‘[Char]’<br>
                  with actual type ‘Maybe String’<br>
    • In the first argument of ‘(++)’, namely ‘f’<br>
      In the expression: f ++ "." ++ s<br>
      In the expression:<br>
        let<br>
          f = fmap head resBDwords<br>
          s = fmap (head . tail) resBDwords<br>
        in f ++ "." ++ s<br>
    |<br>
339 |                                        in f ++ "." ++ s<br>
    |                                           ^<br>
<br>
UpdateSidonie.hs:339:43: error:<br>
    • Couldn't match expected type ‘Maybe String’<br>
                  with actual type ‘[Char]’<br>
    • In the expression: f ++ "." ++ s<br>
      In the expression:<br>
        let<br>
          f = fmap head resBDwords<br>
          s = fmap (head . tail) resBDwords<br>
        in f ++ "." ++ s<br>
      In the expression:<br>
        if lgBDwords == 1 then<br>
            trace "WARNING: BD contains only one word" fmap head resBDwords<br>
        else<br>
            let<br>
              f = fmap head resBDwords<br>
              s = fmap (head . tail) resBDwords<br>
            in f ++ "." ++ s<br>
    |<br>
339 |                                        in f ++ "." ++ s<br>
    |                                           ^^^^^^^^^^^^^<br>
<br>
UpdateSidonie.hs:339:55: error:<br>
    • Couldn't match expected type ‘[Char]’<br>
                  with actual type ‘Maybe String’<br>
    • In the second argument of ‘(++)’, namely ‘s’<br>
      In the second argument of ‘(++)’, namely ‘"." ++ s’<br>
      In the expression: f ++ "." ++ s<br>
    |<br>
339 |                                        in f ++ "." ++ s<br>
    |                                                       ^<br>
Failed, no modules loaded.<br>
<br>
for now this page has been of valuable help:<br>
<br>
<a href="https://pbrisbin.com/posts/maybe_is_just_awesome/" rel="noreferrer noreferrer" target="_blank">https://pbrisbin.com/posts/maybe_is_just_awesome/</a><br>
<br>
i'm sure it's an obvious question but.... :-)<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div>
</div>
</blockquote></div></div>