how can I do this the best

Hello, Im busy with a programm which translates log files to another format. I also have to look if the lines in the old one have the rigtht format. Schould I check the format and also if another field contains a I, E or W. Or schould I do the checking in one clause and make another case on the rest ? Roelof

You should probably ask on the haskell-beginners list instead. And you
should explain in much more detail what you are trying to do.
David
On Feb 21, 2015 3:03 AM, "Roelof Wobben"
Hello,
Im busy with a programm which translates log files to another format. I also have to look if the lines in the old one have the rigtht format.
Schould I check the format and also if another field contains a I, E or W. Or schould I do the checking in one clause and make another case on the rest ?
Roelof
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Hi Roelof,
You forgot to explain what are those fields you are talking about, and what
are I/E/W . Also what are those clauses you are talking about?
Cheers.
21 лют. 2015 09:03, користувач "Roelof Wobben"
Hello,
Im busy with a programm which translates log files to another format. I also have to look if the lines in the old one have the rigtht format.
Schould I check the format and also if another field contains a I, E or W. Or schould I do the checking in one clause and make another case on the rest ?
Roelof
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

So, as the simplest solution -- you need to read file, split it by lines
(convert it to list of lines), for each line check it for validity and
return some result, which would have type, for example
Either String LogMsg
, where Left String indicates error, and other one is Right LogMsg, with
this type:
data LogLevel = LevelW | LevelE | LevelI
data LogMsg = LogMsg LogLevel Int String
Then you would filter all rights to output to new logfile, and filter all
lefts to do whatever you wanted to do with them (you didn't specify this, I
think).
Does this look clear?
Ask if you have more questions!
22 лют. 2015 18:24, користувач "Roelof Wobben"
Sorry,
I stand for Info E stands for Error W stands for Warning.
The clause Im talking about is that the log message must be the format char Int [char] so like this: W 10 this is a warning All the sentences that are not of this format , like for example this one: W this is a false warning , must have another output. That's is also true when the first Char is not a W, E or I.
When it's a W , E, or I then the char must be converted to the word Warning, Error or Info.
I hope it's clear now what I want.
Roelof
Konstantine Rybnikov schreef op 22-2-2015 om 16:17:
Hi Roelof,
You forgot to explain what are those fields you are talking about, and what are I/E/W . Also what are those clauses you are talking about?
Cheers. 21 лют. 2015 09:03, користувач "Roelof Wobben"
написав: Hello,
Im busy with a programm which translates log files to another format. I also have to look if the lines in the old one have the rigtht format.
Schould I check the format and also if another field contains a I, E or W. Or schould I do the checking in one clause and make another case on the rest ?
Roelof
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Note that Roelof is doing the CIS 194 Homework http://www.seas.upenn.edu/~cis194/fall14/hw/03-ADTs.pdf (the older version of fall2014, not the one currently running). This is much clearer than Roelof's description, and gives among other information an algebraic datatype to represent log messages. -- Jedaï

Roelof,
You defined isValid function in the upper-scope first, and then you defined
a symbol (variable) that re-wrote that name to something different (string
"Geldige string"). That's why you get an error saying it doesn't expect
arguments.
My suggestion is to rename second isValid.
Good luck.
On Mon, Feb 23, 2015 at 4:50 PM, Roelof Wobben
Chaddaï Fouché schreef op 23-2-2015 om 13:20:
Note that Roelof is doing the CIS 194 Homework http://www.seas.upenn.edu/~cis194/fall14/hw/03-ADTs.pdf (the older version of fall2014, not the one currently running). This is much clearer than Roelof's description, and gives among other information an algebraic datatype to represent log messages.
-- Jedaï
Correct and Im trying to do exercise 1 of Week 2,
I have tried this solution :
-- | Main entry point to the application. {-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log; import Data.Char (isLetter, isDigit)
isValid :: [Char] -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
parseMessage :: [Char] -> [Char] parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
-- | The main entry point. main :: IO () main = do putStrLn $ parseMessage "I 4764 He trusts to you to set them free,"
but I see this error message :
src/LogAnalysis.hs@16:18-16:27 Couldn't match expected type ‘[Char] -> [Char]’ with actual type [Char] The function isValid is applied to one argument, but its type [Char] has none … In the expression: isValid s In an equation for ‘parseMessage’: parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

The type of `putStrLn` is String -> IO (). `isValid` returns a Bool.
You're probably looking for `print`.
On Mon, Feb 23, 2015 at 9:19 AM, Roelof Wobben
And when Im trying this:
{-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log; import Data.Char (isLetter, isDigit)
isValid :: String -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
-- | The main entry point. main :: IO () main = do putStrLn $ isValid "I 4764 He trusts to you to set them free,"
I see this error message :
src/LogAnalysis.hs@19:16-19:67 Couldn't match type Bool with [Char] Expected type: String Actual type: Bool … In the second argument of ‘($)’, namely ‘isValid "I 4764 He trusts to you to set them free,"’ In a stmt of a 'do' block: putStrLn $ isValid "I 4764 He trusts to you to set them free,"
Roelof
Roelof Wobben schreef op 23-2-2015 om 17:19:
I tried it another way more like explained on this page : http://www.seas.upenn.edu/~cis194/spring13/lectures/02-ADTs.html
so I tried this :
parseMessage :: [Char] -> [Char] parseMessage s case Errornumber of IsDigit Errornumber -> "Geldige string" otherwise -> "Ongeldige string" where Error = s words Errornumber = Error(ErrorNumber _ _ ) Errorcode = Error(_ Errorcode _ )
but now I cannot use where :(
Roelof
Roelof Wobben schreef op 23-2-2015 om 16:10:
Oke,
Then I make there a mistake,
What I try to do is to send the file to parseMessage and let IsValid check if it´s have the right format.
Then after the where I try to check if the function isValid returns true or false.
Roelof
Konstantine Rybnikov schreef op 23-2-2015 om 16:03:
Roelof,
You defined isValid function in the upper-scope first, and then you defined a symbol (variable) that re-wrote that name to something different (string "Geldige string"). That's why you get an error saying it doesn't expect arguments.
My suggestion is to rename second isValid.
Good luck.
On Mon, Feb 23, 2015 at 4:50 PM, Roelof Wobben
wrote: Chaddaï Fouché schreef op 23-2-2015 om 13:20:
Note that Roelof is doing the CIS 194 Homework http://www.seas.upenn.edu/~cis194/fall14/hw/03-ADTs.pdf (the older version of fall2014, not the one currently running). This is much clearer than Roelof's description, and gives among other information an algebraic datatype to represent log messages.
-- Jedaï
Correct and Im trying to do exercise 1 of Week 2,
I have tried this solution :
-- | Main entry point to the application. {-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log; import Data.Char (isLetter, isDigit)
isValid :: [Char] -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
parseMessage :: [Char] -> [Char] parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
-- | The main entry point. main :: IO () main = do putStrLn $ parseMessage "I 4764 He trusts to you to set them free,"
but I see this error message :
src/LogAnalysis.hs@16:18-16:27 Couldn't match expected type ‘[Char] -> [Char]’ with actual type [Char] The function isValid is applied to one argument, but its type [Char] has none … In the expression: isValid s In an equation for ‘parseMessage’: parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing listHaskell-Cafe@haskell.orghttp://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

As Alex mentioned, isValid returns Bool, while type for putStrLn is `String
-> IO ()`. So, in order to print something of type Bool, you need to first
convert it to String. For example, via a function `show`:
putStrLn (show True)
As Alex mentioned, there's a `print` function, which does exactly this:
print x = putStrLn (show x)
You can use it.
On Mon, Feb 23, 2015 at 7:19 PM, Roelof Wobben
And when Im trying this:
{-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log; import Data.Char (isLetter, isDigit)
isValid :: String -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
-- | The main entry point. main :: IO () main = do putStrLn $ isValid "I 4764 He trusts to you to set them free,"
I see this error message :
src/LogAnalysis.hs@19:16-19:67 Couldn't match type Bool with [Char] Expected type: String Actual type: Bool … In the second argument of ‘($)’, namely ‘isValid "I 4764 He trusts to you to set them free,"’ In a stmt of a 'do' block: putStrLn $ isValid "I 4764 He trusts to you to set them free,"
Roelof
Roelof Wobben schreef op 23-2-2015 om 17:19:
I tried it another way more like explained on this page : http://www.seas.upenn.edu/~cis194/spring13/lectures/02-ADTs.html
so I tried this :
parseMessage :: [Char] -> [Char] parseMessage s case Errornumber of IsDigit Errornumber -> "Geldige string" otherwise -> "Ongeldige string" where Error = s words Errornumber = Error(ErrorNumber _ _ ) Errorcode = Error(_ Errorcode _ )
but now I cannot use where :(
Roelof
Roelof Wobben schreef op 23-2-2015 om 16:10:
Oke,
Then I make there a mistake,
What I try to do is to send the file to parseMessage and let IsValid check if it´s have the right format.
Then after the where I try to check if the function isValid returns true or false.
Roelof
Konstantine Rybnikov schreef op 23-2-2015 om 16:03:
Roelof,
You defined isValid function in the upper-scope first, and then you defined a symbol (variable) that re-wrote that name to something different (string "Geldige string"). That's why you get an error saying it doesn't expect arguments.
My suggestion is to rename second isValid.
Good luck.
On Mon, Feb 23, 2015 at 4:50 PM, Roelof Wobben
wrote: Chaddaï Fouché schreef op 23-2-2015 om 13:20:
Note that Roelof is doing the CIS 194 Homework http://www.seas.upenn.edu/~cis194/fall14/hw/03-ADTs.pdf (the older version of fall2014, not the one currently running). This is much clearer than Roelof's description, and gives among other information an algebraic datatype to represent log messages.
-- Jedaï
Correct and Im trying to do exercise 1 of Week 2,
I have tried this solution :
-- | Main entry point to the application. {-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log; import Data.Char (isLetter, isDigit)
isValid :: [Char] -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
parseMessage :: [Char] -> [Char] parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
-- | The main entry point. main :: IO () main = do putStrLn $ parseMessage "I 4764 He trusts to you to set them free,"
but I see this error message :
src/LogAnalysis.hs@16:18-16:27 Couldn't match expected type ‘[Char] -> [Char]’ with actual type [Char] The function isValid is applied to one argument, but its type [Char] has none … In the expression: isValid s In an equation for ‘parseMessage’: parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing listHaskell-Cafe@haskell.orghttp://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Constructors with names like 'Unknown' are a code smell, IMO. I'd just
define the data type like this:
data LogMessage = LogMessage MessageType TimeStamp String
and use `Either String LogMessage` in contexts where parsing can fail:
parseLogEntry :: String -> Either String LogMesage
parseLogEntry str
| isValid str = Right $ mkLogMessage str
| otherwise = Left $ "Poorly-formatted log entry: " ++ str
As for implementing mkLogMessage: you already know how to unpack the parts
of a log message with `words` and pattern matching. After that it's just a
matter of type-casting everything correctly and passing it to the
`LogMessage` constructor.
On Mon, Feb 23, 2015 at 10:14 AM, Roelof Wobben
Thanks,
This works :
-- | Main entry point to the application. {-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Data.Char (isLetter, isDigit)
isValid :: String -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
-- | The main entry point. main :: IO () main = do putStrLn $ ( show (isValid "I 656 He trusts to you to set them free,"))
Now I have to ty to find out how I can check if a has the contents of I/W/E and how to make the right output (Error/Warning/Info 22) " Text" ) and then make it work with this datatype :
data LogMessage = LogMessage MessageType TimeStamp String | Unknown String deriving (Show, Eq)
Roelof
Konstantine Rybnikov schreef op 23-2-2015 om 18:49:
As Alex mentioned, isValid returns Bool, while type for putStrLn is `String -> IO ()`. So, in order to print something of type Bool, you need to first convert it to String. For example, via a function `show`:
putStrLn (show True)
As Alex mentioned, there's a `print` function, which does exactly this:
print x = putStrLn (show x)
You can use it.
On Mon, Feb 23, 2015 at 7:19 PM, Roelof Wobben
wrote: And when Im trying this:
{-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log; import Data.Char (isLetter, isDigit)
isValid :: String -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
-- | The main entry point. main :: IO () main = do putStrLn $ isValid "I 4764 He trusts to you to set them free,"
I see this error message :
src/LogAnalysis.hs@19:16-19:67 Couldn't match type Bool with [Char] Expected type: String Actual type: Bool … In the second argument of ‘($)’, namely ‘isValid "I 4764 He trusts to you to set them free,"’ In a stmt of a 'do' block: putStrLn $ isValid "I 4764 He trusts to you to set them free,"
Roelof
Roelof Wobben schreef op 23-2-2015 om 17:19:
I tried it another way more like explained on this page : http://www.seas.upenn.edu/~cis194/spring13/lectures/02-ADTs.html
so I tried this :
parseMessage :: [Char] -> [Char] parseMessage s case Errornumber of IsDigit Errornumber -> "Geldige string" otherwise -> "Ongeldige string" where Error = s words Errornumber = Error(ErrorNumber _ _ ) Errorcode = Error(_ Errorcode _ )
but now I cannot use where :(
Roelof
Roelof Wobben schreef op 23-2-2015 om 16:10:
Oke,
Then I make there a mistake,
What I try to do is to send the file to parseMessage and let IsValid check if it´s have the right format.
Then after the where I try to check if the function isValid returns true or false.
Roelof
Konstantine Rybnikov schreef op 23-2-2015 om 16:03:
Roelof,
You defined isValid function in the upper-scope first, and then you defined a symbol (variable) that re-wrote that name to something different (string "Geldige string"). That's why you get an error saying it doesn't expect arguments.
My suggestion is to rename second isValid.
Good luck.
On Mon, Feb 23, 2015 at 4:50 PM, Roelof Wobben
wrote: Chaddaï Fouché schreef op 23-2-2015 om 13:20:
Note that Roelof is doing the CIS 194 Homework http://www.seas.upenn.edu/~cis194/fall14/hw/03-ADTs.pdf (the older version of fall2014, not the one currently running). This is much clearer than Roelof's description, and gives among other information an algebraic datatype to represent log messages.
-- Jedaï
Correct and Im trying to do exercise 1 of Week 2,
I have tried this solution :
-- | Main entry point to the application. {-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log; import Data.Char (isLetter, isDigit)
isValid :: [Char] -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
parseMessage :: [Char] -> [Char] parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
-- | The main entry point. main :: IO () main = do putStrLn $ parseMessage "I 4764 He trusts to you to set them free,"
but I see this error message :
src/LogAnalysis.hs@16:18-16:27 Couldn't match expected type ‘[Char] -> [Char]’ with actual type [Char] The function isValid is applied to one argument, but its type [Char] has none … In the expression: isValid s In an equation for ‘parseMessage’: parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing listHaskell-Cafe@haskell.orghttp://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

You can pattern match on string literals:
parseMessage :: String -> String
parseMessage s = go (words s)
where
go ("I":_:_) = "Info"
go _ = "false"
You don't need to call it "go2", btw. Functions in where-blocks don't leak
into the global scope, so there's no conflict with the `go` in your other
function.
On Mon, Feb 23, 2015 at 12:15 PM, Roelof Wobben
Sorry ,
I cannot change that function. I have to use it,
But I think I found a solution for a step earlier,
To parse a line and change it to another line which will be a member of LogMessage :
-- | Main entry point to the application. {-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Data.Char (isLetter, isDigit)
isValid :: String -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
parseMessage :: String -> String parseMessage s = go2 (words s) where go2 (a:_:_) = case a of "I" -> "Info " _ -> "False"
go2 _ = "false"
-- | The main entry point. main :: IO () main = do putStrLn $ parseMessage "I 656 He trusts to you to set them free,"
But I feels wierd, to use first a pattern matching and later do a case of. Is this a good way or are there better ways,
Roelfo
Alex Hammel schreef op 23-2-2015 om 21:01:
Constructors with names like 'Unknown' are a code smell, IMO. I'd just define the data type like this:
data LogMessage = LogMessage MessageType TimeStamp String
and use `Either String LogMessage` in contexts where parsing can fail:
parseLogEntry :: String -> Either String LogMesage parseLogEntry str | isValid str = Right $ mkLogMessage str | otherwise = Left $ "Poorly-formatted log entry: " ++ str
As for implementing mkLogMessage: you already know how to unpack the parts of a log message with `words` and pattern matching. After that it's just a matter of type-casting everything correctly and passing it to the `LogMessage` constructor.
On Mon, Feb 23, 2015 at 10:14 AM, Roelof Wobben
wrote: Thanks,
This works :
-- | Main entry point to the application. {-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Data.Char (isLetter, isDigit)
isValid :: String -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
-- | The main entry point. main :: IO () main = do putStrLn $ ( show (isValid "I 656 He trusts to you to set them free,"))
Now I have to ty to find out how I can check if a has the contents of I/W/E and how to make the right output (Error/Warning/Info 22) " Text" ) and then make it work with this datatype :
data LogMessage = LogMessage MessageType TimeStamp String | Unknown String deriving (Show, Eq)
Roelof
Konstantine Rybnikov schreef op 23-2-2015 om 18:49:
As Alex mentioned, isValid returns Bool, while type for putStrLn is `String -> IO ()`. So, in order to print something of type Bool, you need to first convert it to String. For example, via a function `show`:
putStrLn (show True)
As Alex mentioned, there's a `print` function, which does exactly this:
print x = putStrLn (show x)
You can use it.
On Mon, Feb 23, 2015 at 7:19 PM, Roelof Wobben
wrote: And when Im trying this:
{-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log; import Data.Char (isLetter, isDigit)
isValid :: String -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
-- | The main entry point. main :: IO () main = do putStrLn $ isValid "I 4764 He trusts to you to set them free,"
I see this error message :
src/LogAnalysis.hs@19:16-19:67 Couldn't match type Bool with [Char] Expected type: String Actual type: Bool … In the second argument of ‘($)’, namely ‘isValid "I 4764 He trusts to you to set them free,"’ In a stmt of a 'do' block: putStrLn $ isValid "I 4764 He trusts to you to set them free,"
Roelof
Roelof Wobben schreef op 23-2-2015 om 17:19:
I tried it another way more like explained on this page : http://www.seas.upenn.edu/~cis194/spring13/lectures/02-ADTs.html
so I tried this :
parseMessage :: [Char] -> [Char] parseMessage s case Errornumber of IsDigit Errornumber -> "Geldige string" otherwise -> "Ongeldige string" where Error = s words Errornumber = Error(ErrorNumber _ _ ) Errorcode = Error(_ Errorcode _ )
but now I cannot use where :(
Roelof
Roelof Wobben schreef op 23-2-2015 om 16:10:
Oke,
Then I make there a mistake,
What I try to do is to send the file to parseMessage and let IsValid check if it´s have the right format.
Then after the where I try to check if the function isValid returns true or false.
Roelof
Konstantine Rybnikov schreef op 23-2-2015 om 16:03:
Roelof,
You defined isValid function in the upper-scope first, and then you defined a symbol (variable) that re-wrote that name to something different (string "Geldige string"). That's why you get an error saying it doesn't expect arguments.
My suggestion is to rename second isValid.
Good luck.
On Mon, Feb 23, 2015 at 4:50 PM, Roelof Wobben
wrote: Chaddaï Fouché schreef op 23-2-2015 om 13:20:
Note that Roelof is doing the CIS 194 Homework http://www.seas.upenn.edu/~cis194/fall14/hw/03-ADTs.pdf (the older version of fall2014, not the one currently running). This is much clearer than Roelof's description, and gives among other information an algebraic datatype to represent log messages.
-- Jedaï
Correct and Im trying to do exercise 1 of Week 2,
I have tried this solution :
-- | Main entry point to the application. {-# OPTIONS_GHC -Wall #-}
module LogAnalysis where
import Log; import Data.Char (isLetter, isDigit)
isValid :: [Char] -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
parseMessage :: [Char] -> [Char] parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
-- | The main entry point. main :: IO () main = do putStrLn $ parseMessage "I 4764 He trusts to you to set them free,"
but I see this error message :
src/LogAnalysis.hs@16:18-16:27 Couldn't match expected type ‘[Char] -> [Char]’ with actual type [Char] The function isValid is applied to one argument, but its type [Char] has none … In the expression: isValid s In an equation for ‘parseMessage’: parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing listHaskell-Cafe@haskell.orghttp://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

On 24/02/2015, at 5:19 am, Roelof Wobben
I tried it another way more like explained on this page : http://www.seas.upenn.edu/~cis194/spring13/lectures/02-ADTs.html
so I tried this :
parseMessage :: [Char] -> [Char] parseMessage s case Errornumber of IsDigit Errornumber -> "Geldige string" otherwise -> "Ongeldige string" where Error = s words Errornumber = Error(ErrorNumber _ _ ) Errorcode = Error(_ Errorcode _ )
but now I cannot use where :(
That's not your problem. IsDigit ErrorNumber is not a pattern. parseMessage s = if isDigit errorNumber then "Geldige string" else "Ongelidige string" where errorNumber = ??? is OK. Now I cannot make sense of Error = s words identifiers beginning with capital letters are used for - module names - type constructors - data constructors You want a variable here, so it must begin with a lower case letter. s words treats a string s as a function and applies it to the function words as argument: s(words). But that does not type check. You mean words s. The result of words s, whatever else it may be, is not an error. Errornumber = Error(ErrorNumber _ _) In the form "expr where pattern = expr", the thing after the equal sign must be an expression. But Error(ErrorNumber _ _) is not an expression. "_" is a PATTERN (= I do not care what goes here) but never an EXPRESSION (because what value would it have?).

From the homework:
data MessageType = Info
| Warning
| Error Int
deriving (Show, Eq)
data LogMessage = LogMessage MessageType TimeStamp String
deriving (Eq, Show)
data MaybeLogMessage = ValidM LogMessage -- A valid msg
| InvalidLM String -- Invalid msg
parseMessage :: String -> MaybeLogMessage
parseMessage = undefined
To implement parseMessage, we consume the string from left to right
word-by-word.
If the first word is E, then we read the second word as in integer
indicating severity and proceed further.
Info and Warning don't require more information, so the next word will be
the timestamp in those cases.
If the pattern fails anywhere, we return the whole string as an InvalidLM.
Hope this helps.
On 24 February 2015 at 06:37, Richard A. O'Keefe
On 24/02/2015, at 5:19 am, Roelof Wobben
wrote: I tried it another way more like explained on this page : http://www.seas.upenn.edu/~cis194/spring13/lectures/02-ADTs.html
so I tried this :
parseMessage :: [Char] -> [Char] parseMessage s case Errornumber of IsDigit Errornumber -> "Geldige string" otherwise -> "Ongeldige string" where Error = s words Errornumber = Error(ErrorNumber _ _ ) Errorcode = Error(_ Errorcode _ )
but now I cannot use where :(
That's not your problem.
IsDigit ErrorNumber is not a pattern.
parseMessage s = if isDigit errorNumber then "Geldige string" else "Ongelidige string" where errorNumber = ???
is OK.
Now I cannot make sense of Error = s words
identifiers beginning with capital letters are used for - module names - type constructors - data constructors You want a variable here, so it must begin with a lower case letter.
s words treats a string s as a function and applies it to the function words as argument: s(words). But that does not type check. You mean words s.
The result of words s, whatever else it may be, is not an error.
Errornumber = Error(ErrorNumber _ _)
In the form "expr where pattern = expr", the thing after the equal sign must be an expression. But Error(ErrorNumber _ _) is not an expression. "_" is a PATTERN (= I do not care what goes here) but never an EXPRESSION (because what value would it have?).
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
-- Regards Sumit Sahrawat

On 24/02/2015, at 3:50 am, Roelof Wobben
isValid :: [Char] -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False
My attention was caught by the remarkably unhelpful name "go". What goes? Where does it go? What does going mean? This is a good time to use a 'case': isValid s = case words s of [a]:b:_ -> isLetter a && all isDigit b _ -> False
parseMessage :: [Char] -> [Char]
parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string"
In the first line of this function, you are calling isValid with an argument. But you are defining isValid to be a string! parseMessage s = if isValid s then "Geldige string" else "Ongeldige string" "parseMessage: is a bad name because the purpose of the function is *NOT* to break the message into parts and deliver those parts but to CHECK or VALIDATE or CLASSIFY the message. The code import Data.Char isValid s = case words s of [a]:b:_ -> isLetter a && all isDigit b _ -> False parseMessage s = if isValid s then "Geldige string" else "Ongeldige string" main = putStrLn $ parseMessage "I 4764 He trusts to you to set them free," compiles without warnings and produces the result I think you want.

Thanks, I rewrote it like this : parseMessage :: String -> LogMessage parseMessage s = case words s of ("I":time:text) -> LogMessage Info (read time) (unwords text) ("W":time:text) -> LogMessage Warning (read time) (unwords text) ("E":errorcode:time:text) -> LogMessage Error (read errorcode) (read time) (unwords text) _ -> Unknown "This is not in the right format" The only thing Im facing now It the Error part. Messagetype has this signature : data MessageType = Info | Warning | Error Int deriving (Show, Eq) So Error has a Messagatype which contains 2 things. but because of the use of words I looks like this I think [ "E", 46, 23456 , "This", "is", "a", "error". ] Can I somehow use unwords here to to make the Messagetype work. Roelof Richard A. O'Keefe schreef op 24-2-2015 om 2:01:
On 24/02/2015, at 3:50 am, Roelof Wobben
wrote: isValid :: [Char] -> Bool isValid s = go (words s) where go ([a]:b:_) = isLetter a && all isDigit b go _ = False My attention was caught by the remarkably unhelpful name "go". What goes? Where does it go? What does going mean?
This is a good time to use a 'case':
isValid s = case words s of [a]:b:_ -> isLetter a && all isDigit b _ -> False
parseMessage :: [Char] -> [Char]
parseMessage s = isValid s where isValid = "Geldige string" _ = "Ongeldige string" In the first line of this function, you are calling isValid with an argument. But you are defining isValid to be a string!
parseMessage s = if isValid s then "Geldige string" else "Ongeldige string"
"parseMessage: is a bad name because the purpose of the function is *NOT* to break the message into parts and deliver those parts but to CHECK or VALIDATE or CLASSIFY the message.
The code
import Data.Char
isValid s = case words s of [a]:b:_ -> isLetter a && all isDigit b _ -> False
parseMessage s = if isValid s then "Geldige string" else "Ongeldige string"
main = putStrLn $ parseMessage "I 4764 He trusts to you to set them free,"
compiles without warnings and produces the result I think you want.

On 24 February 2015 at 13:22, Roelof Wobben
Thanks,
I rewrote it like this :
parseMessage :: String -> LogMessage parseMessage s = case words s of ("I":time:text) -> LogMessage Info (read time) (unwords text) ("W":time:text) -> LogMessage Warning (read time) (unwords text) ("E":errorcode:time:text) -> LogMessage Error (read errorcode) (read time) (unwords text) _ -> Unknown "This is not in the right format"
The code looks just fine. Great work. The trouble is with the third case. The error message is fairly instructive. log.hs:19:36: Couldn't match expected type ‘String -> LogMessage’ with actual type ‘LogMessage’ The function ‘LogMessage’ is applied to four arguments, but its type ‘MessageType -> TimeStamp -> String -> LogMessage’ has only three In the expression: LogMessage Error (read errorcode) (read time) (unwords text) In a case alternative: ("E" : errorcode : time : text) -> LogMessage Error (read errorcode) (read time) (unwords text) log.hs:19:47: Couldn't match expected type ‘MessageType’ with actual type ‘Int -> MessageType’ Probable cause: ‘Error’ is applied to too few arguments In the first argument of ‘LogMessage’, namely ‘Error’ In the expression: LogMessage Error (read errorcode) (read time) (unwords text) Long story short, you meant to write LogMessage (Error (read errorcode)) ... instead of LogMessage Error (read errorcode) ... -- Too many arguments to LogMessage (error message 1) -- Too few arguments to Error (error message 2) which is a very common error.
participants (7)
-
Alex Hammel
-
Chaddaï Fouché
-
David Feuer
-
Konstantine Rybnikov
-
Richard A. O'Keefe
-
Roelof Wobben
-
Sumit Sahrawat, Maths & Computing, IIT (BHU)