<div dir="ltr">f has the wrong type. It needs to return a value in the IO monad. For instance:<div><br></div><div>f: String -> IO String</div><div>f s = return (s ++ "!")</div><div><br></div><div>g :: IO String</div><div>g = readLn >>= f</div><div><br></div><div>You could also let f return a value of a type other than String, say:</div><div><br></div><div>f :: String -> IO ()</div><div>f = print</div><div><br></div><div>The type of >>= tells you this: Monad m => m a -> (a -> m b) -> m b. The second argument has type a -> m b. String -> IO () or String -> IO String both match that.</div><div><br></div><div>As a warning, readLn expects a Haskell value, and f requires that it be a string. So you have to type in a string the way you would in a program, as "Hello" or ['H', 'e', 'l', 'l', 'o'] or you'll get a parse failure.</div><div><br></div><div><div class="gmail_extra"><div class="gmail_quote">On Thu, Jan 15, 2015 at 2:44 PM, Miro Karpis <span dir="ltr"><<a href="mailto:miroslav.karpis@gmail.com" target="_blank">miroslav.karpis@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Many thanks everyone,.. but I'm not so confident with monads. If I understand I could translate with them for example IO String to String? If this is true I'm having troubles to achieve this.<br><br></div><div>Here is my simple test (only to test the logic), which ends with error:<br></div><div><br> Couldn't match type ‘[]’ with ‘IO’<br> Expected type: IO Char<br> Actual type: String<br> In the expression: f a<br> In the second argument of ‘(>>=)’, namely ‘(\ a -> f a)’<br><br><br><br></div>g = readLn<br> >>= (\a -> f a)<br><br>f :: String -> String<br>f s_ = s_ ++ "!"<br><div><br><br><br></div><div>Cheers, Miro<br></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 15, 2015 at 5:42 PM, Mike Meyer <span dir="ltr"><<a href="mailto:mwm@mired.org" target="_blank">mwm@mired.org</a>></span> wrote:<br><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 class="gmail_extra"><div class="gmail_quote"><span>On Thu, Jan 15, 2015 at 9:24 AM, Dimitri DeFigueiredo <span dir="ltr"><<a href="mailto:defigueiredo@ucdavis.edu" target="_blank">defigueiredo@ucdavis.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
I would not say that the problem is with the guard check. The
problem is with 'null'. It's type is<br>
<br>
Prelude> :t null<br>
null :: [a] -> Bool<br>
<br>
So, it expects a list of something, rather than an IO of something,
whence the complaint.<br><div></div></div></blockquote><div><br></div><div><br></div></span><div>While that's the source of the error, the problem is the combination of the guard check and where to bind a value in the IO monad.</div><div><br></div><div>Guard checks must have a value of Bool. getDBRecord returns something of type IO [Int]. Where just binds a name, so you either need a way to extract the [Int] from the return value before binding it in the where, or a function of type IO [Int] -> Bool for the guard.</div><div><br></div><div>Note that this isn't an IO issue but a monad issue. There isn't a monad method that returns a value not in the monad, so you can't write either of the two options above using monad methods. The best solution is the one already proposed - write a function from [Int] -> IO String, and use bind (>>=) on that function to handle things. You could also use the do sugaring of <- to get a less functional version.</div><div><br></div><div>The last option is to use the IO-specific function unsafePerformIO to write something like nullIO = null . unsafePerformIO. But it's called UNSAFE and tucked away in a module of similar operations for a reason. Using bind is much preferred.</div><div><div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000"><div>On 15/01/15 09:51, Miro Karpis wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div>
<div>
<div>
<div>Hi,<br>
<br>
</div>
please is there a way to have guards with 'where' that
communicates with IO? Or is there some other more elegant
way? I can do this with classic if/else,...but I just find
it nicer with guards.<br>
<br>
<br>
</div>
I have something like this (just an example):<br>
<br>
<br>
f :: Int -> IO String<br>
f x<br>
| null dbOutput = return "no db record"<br>
| otherwise = return "we got some db records"<br>
where dbOutput = getDBRecord x<br>
<br>
<br>
getDBRecord :: Int -> IO [Int]<br>
getDBRecord recordId = do<br>
putStrLn $ "checking dbRecord" ++ show recordId<br>
--getting data from DB<br>
return [1,2]<br>
<br>
<br>
</div>
<div>problem is that db dbOutput is IO and the guard check
does not like it:<br>
<br>
Couldn't match expected type ‘[a0]’ with actual type ‘IO
[Int]’<br>
In the first argument of ‘null’, namely ‘dbOutput’<br>
In the expression: null dbOutput<br>
<br>
<br>
</div>
<div><br>
</div>
Cheers,<br>
</div>
Miro<br>
</div>
<br>
<fieldset></fieldset>
<br>
<pre>_______________________________________________
Beginners mailing list
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a>
</pre>
</blockquote>
<br>
</div>
<br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
<br></blockquote></div></div></div><br></div></div>
<br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div></div></div></div>
<br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div></div></div>