[Haskell-beginners] help with IO guards
Mike Meyer
mwm at mired.org
Thu Jan 15 21:01:19 UTC 2015
f has the wrong type. It needs to return a value in the IO monad. For
instance:
f: String -> IO String
f s = return (s ++ "!")
g :: IO String
g = readLn >>= f
You could also let f return a value of a type other than String, say:
f :: String -> IO ()
f = print
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.
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.
On Thu, Jan 15, 2015 at 2:44 PM, Miro Karpis <miroslav.karpis at gmail.com>
wrote:
> 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.
>
> Here is my simple test (only to test the logic), which ends with error:
>
> Couldn't match type ‘[]’ with ‘IO’
> Expected type: IO Char
> Actual type: String
> In the expression: f a
> In the second argument of ‘(>>=)’, namely ‘(\ a -> f a)’
>
>
>
> g = readLn
> >>= (\a -> f a)
>
> f :: String -> String
> f s_ = s_ ++ "!"
>
>
>
> Cheers, Miro
>
> On Thu, Jan 15, 2015 at 5:42 PM, Mike Meyer <mwm at mired.org> wrote:
>
>> 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
>>>
>>>
>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://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/66ef96a9/attachment.html>
More information about the Beginners
mailing list