
Hi, all! When I compile my program below, ghc emits Type error. Since the return type of foo Func is IO String and first case statement has "return timedVal", I think that ghc expects the type of timedVal as String. However, the error message shows that ghc expects timedVal should have type IO b0. What am I missing? Any comments are appreciated. Thanks in advance! Chul-Woong -- import Data.Time.LocalTime (getZonedTime, zonedTimeToUTC) import System.Locale (defaultTimeLocale) import Data.Time.Format (formatTime) import Data.Time.Clock (UTCTime) currentUTCTime :: IO UTCTime currentUTCTime = do zTime <- getZonedTime return (zonedTimeToUTC zTime) fooFunc :: IO String fooFunc = do putStrLn "Hello, world" barFunc "xutc" where barFunc s = case s of "apple" -> return s ('x': val) -> return timedVal where timedVal = case val of "utc" -> do utcTime <- currentUTCTime formatTime defaultTimeLocale "%a" utcTime --- Prelude> :l test [1 of 1] Compiling Main ( test.hs, interpreted ) test.hs:21:57: Couldn't match expected type `IO b0' with actual type `String' In the return type of a call of `formatTime' In a stmt of a 'do' block: formatTime defaultTimeLocale "%a" utcTime In the expression: do { utcTime <- currentUTCTime; formatTime defaultTimeLocale "%a" utcTime }

On 07/23/2014 03:08 PM, 양철웅 wrote:
Hi, all!
Hi, Code attached and online: http://lpaste.net/107954 If you look at the formatTime docs [1] you'll see that it returns a "String" not an "IO String" as you expected in the original code, so we need to wrap that in the IO monad using "return", because on the "utc" case branch you're in a monad (keyword: "do"). After doing this modification we bound an IO String to timedVal in the where clause, thus it's no longer necessary to "return timedVal" on the ('x': val) branch of the first case since timedVal is already an IO monad containing a string. Hope this helps. PS: Also if I were you, I'd extract the barFunc function form the fooFunc function and write it as a standalone with explicit types, too. For me, seeing the types helps a lot. http://hackage.haskell.org/package/time-1.4.2/docs/Data-Time-Format.html#v:f... -- Barbu Paul - Gheorghe Common sense is not so common - Voltaire Visit My GitHub profile to see my open-source projects - https://github.com/paullik

On 7/23/2014 3:08 PM, 양철웅 wrote: Look at the error:
test.hs:21:57: Couldn't match expected type `IO b0' with actual type `String' In the return type of a call of `formatTime' In a stmt of a 'do' block: formatTime defaultTimeLocale "%a" utcTime In the expression: do { utcTime <- currentUTCTime; formatTime defaultTimeLocale "%a" utcTime } Rewriting that do-block a little, we get: do utcTime <- currentUTCTime problem where problem = formatTime defaultTimeLocale "%a" utcTime
In plain English, GHC's error message means:
On line 21 of test.hs, column 57: I (GHC) inferred from the context surrounding it that 'problem' should have the type 'IO a' for some a. However, you defined 'problem' in a way that makes its type be 'String'. Therefore, I can't accept your program.
Do you see what caused the error? How would you fix it? HTH, Gesh

On Wed, Jul 23, 2014 at 7:08 PM, 양철웅
Since the return type of foo Func is IO String and first case statement has "return timedVal", I think that ghc expects the type of timedVal as String. However, the error message shows that ghc expects timedVal should have type IO b0.
It's not really about timedVal nor the case 'statement'. (The scare quotes are because there are only expressions, not statements, in haskell.) Consider the difference between do { putStrLn "hello"; True; } and do { putStrLn "hello"; return True; } Which one throws an error and why? -- Kim-Ee

Thank you all for kind replies.
But I'm not sure whether I grasp the gist.
Actual code is as follows.
I want to scan the query argument of HTTP get method and
build response object according to the query arguments.
I use fold and the scanQuery function should return IO object
for some reason.
Since parseHeader function is fold function and uses query and request
variable at the same time, I cannot write as a separate function.
scanQuery :: Request -> IO Object
scanQuery request = do
let (p, query) = parseUrl (path request)
foldM parseHeader defObject query
where parseHeader obj (name, Just value) =
case name of
"len" -> return obj { contentLength = read value }
"type" -> return obj { contentType =
parseContentType value }
"rate" -> return obj { rate = Just value }
"status" -> return obj { httpStatus = read value }
('x':'x':name2) -> return obj { clientReqHdr =
((name2, vv) : prev) }
where prev = clientReqHdr obj
vv = case value of
"client_ip_addr" -> clientIp request
"now" -> do utcTime <-
currentUTCTime
return $ formatRFC1123
utcTime
_ -> value
_ -> return obj
However, above code does not compile also :-(
*Main> :l test
[1 of 1] Compiling Main ( test.hs, interpreted )
test.hs:101:64:
Couldn't match expected type `[t0]' with actual type `IO UTCTime'
In a stmt of a 'do' block: utcTime <- currentUTCTime
In the expression:
do { utcTime <- currentUTCTime;
return $ formatRFC1123 utcTime }
In a case alternative:
"now"
-> do { utcTime <- currentUTCTime;
return $ formatRFC1123 utcTime }
Failed, modules loaded: none.
Obviously outer do-block is inside IO monad, as the type of scanQuery is
Request -> IO Object. But GHC puts inner do-block (in "now" case) inside
list monad,
doesn't it? Why does ghc look for List monad?
Lost in monad,
Chul-Woong
2014-07-23 21:33 GMT+09:00 Kim-Ee Yeoh
On Wed, Jul 23, 2014 at 7:08 PM, 양철웅
wrote: Since the return type of foo Func is IO String and first case statement has "return timedVal", I think that ghc expects the type of timedVal as String. However, the error message shows that ghc expects timedVal should have type IO b0.
It's not really about timedVal nor the case 'statement'. (The scare quotes are because there are only expressions, not statements, in haskell.)
Consider the difference between
do { putStrLn "hello"; True; }
and
do { putStrLn "hello"; return True; }
Which one throws an error and why?
-- Kim-Ee
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Wed, Jul 23, 2014 at 10:18 AM, 양철웅
('x':'x':name2) -> return obj { clientReqHdr = ((name2, vv) : prev) } where prev = clientReqHdr obj vv = case value of "client_ip_addr" -> clientIp request "now" -> do utcTime <- currentUTCTime return $ formatRFC1123 utcTime _ -> value _ -> return obj
However, above code does not compile also :-( *Main> :l test [1 of 1] Compiling Main ( test.hs, interpreted )
test.hs:101:64: Couldn't match expected type `[t0]' with actual type `IO UTCTime' In a stmt of a 'do' block: utcTime <- currentUTCTime In the expression: do { utcTime <- currentUTCTime; return $ formatRFC1123 utcTime } In a case alternative: "now" -> do { utcTime <- currentUTCTime; return $ formatRFC1123 utcTime } Failed, modules loaded: none.
Obviously outer do-block is inside IO monad, as the type of scanQuery is Request -> IO Object. But GHC puts inner do-block (in "now" case) inside list monad, doesn't it? Why does ghc look for List monad?
Because you're treating vv as a pure value when you use it, so ghc looks for a way to treat it as a monad and concludes that it is a List. If you want it to be in IO, you need to use <- on its result, not use it directly. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Thank you, Brandon.
I changed the code like belows and it works.
('x':'x':name2) -> do vv <- case value of
"client_ip_addr" ->
return $ clientIp request
"now" -> do utcTime
<- currentUTCTime
return $
formatRFC1123 utcTime
_ -> return value
let prev = clientReqHdr obj
return obj { clientReqHdr =
((name2, vv) : prev) }
2014-07-23 23:22 GMT+09:00 Brandon Allbery
On Wed, Jul 23, 2014 at 10:18 AM, 양철웅
wrote: ('x':'x':name2) -> return obj { clientReqHdr = ((name2, vv) : prev) } where prev = clientReqHdr obj vv = case value of "client_ip_addr" -> clientIp request "now" -> do utcTime <- currentUTCTime return $ formatRFC1123 utcTime _ -> value _ -> return obj
However, above code does not compile also :-( *Main> :l test [1 of 1] Compiling Main ( test.hs, interpreted )
test.hs:101:64: Couldn't match expected type `[t0]' with actual type `IO UTCTime' In a stmt of a 'do' block: utcTime <- currentUTCTime In the expression: do { utcTime <- currentUTCTime; return $ formatRFC1123 utcTime } In a case alternative: "now" -> do { utcTime <- currentUTCTime; return $ formatRFC1123 utcTime } Failed, modules loaded: none.
Obviously outer do-block is inside IO monad, as the type of scanQuery is Request -> IO Object. But GHC puts inner do-block (in "now" case) inside list monad, doesn't it? Why does ghc look for List monad?
Because you're treating vv as a pure value when you use it, so ghc looks for a way to treat it as a monad and concludes that it is a List. If you want it to be in IO, you need to use <- on its result, not use it directly.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Wed, Jul 23, 2014 at 9:45 PM, 양철웅
I changed the code like belows and it works.
On a higher-level, you might want to reconsider the design of that function called parseHeader. It has type: (a -> IO b) only because there's a special case "now" which apparently requires querying for the current time. Other than that, it's a pure function. Is there a way to make it a pure function? -- Kim-Ee

Yes. I found that issue and change the function to pure form which receives
time as input argument.
When I tried to code in C++, I found myself coding in C only to feed the
sources to g++.
I found myself coding in do-block for majority of Haskell code now. :-(
Thanks Yeoh!
2014-07-24 16:56 GMT+09:00 Kim-Ee Yeoh
On Wed, Jul 23, 2014 at 9:45 PM, 양철웅
wrote: I changed the code like belows and it works.
On a higher-level, you might want to reconsider the design of that function called parseHeader.
It has type: (a -> IO b) only because there's a special case "now" which apparently requires querying for the current time. Other than that, it's a pure function.
Is there a way to make it a pure function?
-- Kim-Ee
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (6)
-
Barbu Paul - Gheorghe
-
Brandon Allbery
-
Chul-Woong Yang
-
Gesh
-
Kim-Ee Yeoh
-
양철웅