I have a function which i must use and it is named :
hPutStrLn
That function has a type :
hPutStrLn::Handle -> String -> IO ()<
The simplest approach is with do notation. You could define an auxiliary function to pass to hPutDocument:
doGrep :: Handle -> IO ()
doGrep h =
do
str <- readProcess "grep" ["-n",s,"camera2.owl"] ""
hPutStrLn h str
tryA (arrIO (\s -> hPutDocument doGrep))
One way to think of it is that it allows you to convert an IO String to a String, but only within the scope of the do block, and the entire do block ends up having an IO type - IO () in this case.
You can't convert an IO String to a String in an arbitrary context, because Haskell's type system is designed to stop you from treating impure values that come from external sources being treated as pure - the IO type indicates that the value may have come from doing some kind of IO.
You can also use the >>= operator (pronounced "bind") directly in your call to hPutDocument:
hPutDocument (\h -> readProcess "grep" ["-n",s,"camera2.owl"] ""
>>= \str -> hPutrStrLn h str)
>>= has this type:
(>>=) :: IO a -> (a -> IO b) -> IO b
In this particular case, a = String and b = ().
So here >>= takes the IO String produced by readProcess ... and passes it to the second argument, which is a function that takes a String and produces an IO (). The overall result is the IO () produced by the second function.
The notation \str -> hPutStrLn h str defines an anonymous function (a "lambda") that takes str as an argument and produces the result of hPutStrLn h str.
The do notation above is actually translated ("desugared") to this by the compiler.
In this particular instance you can also shorten \str -> hPutrStrLn h str to just hPutStrLn h, and you could also use the reverse bind operator =<< to produce something as close as possible to your original code:
hPutDocument (\h -> hPutStrLn h =<< readProcess "grep" ["-n",s,"camera2.owl"] "")
Shortening \str -> hPutStrLn h str works because of partial application ("currying"). A function that takes multiple arguments can be just given some of them (in order), giving back a function that expects the remaining arguments.
Since hPutStrLn has type Handle -> String -> IO (), hPutStrLn h has type String -> IO (), so long as h has type Handle.