[Haskell-beginners] help with IO guards

Mike Meyer mwm at mired.org
Thu Jan 15 16:42:27 UTC 2015


On Thu, Jan 15, 2015 at 9:24 AM, Dimitri DeFigueiredo <
defigueiredo at ucdavis.edu> wrote:

>  I would not say that the problem is with the guard check. The problem is
> with 'null'. It's type is
>
> Prelude> :t null
> null :: [a] -> Bool
>
> So, it expects a list of something, rather than an IO of something, whence
> the complaint.
>


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.

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.

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.

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.


> On 15/01/15 09:51, Miro Karpis wrote:
>
>   Hi,
>
>  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.
>
>
>  I have something like this (just an example):
>
>
> f :: Int -> IO String
> f x
>     | null dbOutput = return "no db record"
>     | otherwise = return "we got some db records"
>     where dbOutput = getDBRecord x
>
>
> getDBRecord :: Int -> IO [Int]
> getDBRecord recordId = do
>     putStrLn $ "checking dbRecord" ++ show recordId
>     --getting data from DB
>     return [1,2]
>
>
>  problem is that db dbOutput is IO and the guard check does not like it:
>
> Couldn't match expected type ‘[a0]’ with actual type ‘IO [Int]’
>     In the first argument of ‘null’, namely ‘dbOutput’
>     In the expression: null dbOutput
>
>
>
>  Cheers,
>  Miro
>
>
> _______________________________________________
> Beginners mailing listBeginners at haskell.orghttp://www.haskell.org/mailman/listinfo/beginners
>
>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20150115/ff8a16b9/attachment.html>


More information about the Beginners mailing list