Using output of head in data constuctor

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Using output of head in data constuctor

Josh Friedlander
Given the following code:

module Log where
import Control.Applicative

data MessageType = Info
                 | Warning
                 | Error Int

type TimeStamp = Int

data LogMessage = LogMessage MessageType TimeStamp String
                | Unknown String

I want to create a log parser like this:

module LogAnalysis where
import Log

parseMessage :: String -> LogMessage
parseMessage xs
  | length(words(xs)) < 3 = Unknown xs
  | notElem(head(words(xs)) ["I", "E", "W"]) = Unknown xs
  | otherwise = LogMessage Info 3 head(words(xs))

But GHC gives me "• Couldn't match type ‘[a0] -> a0’ with ‘[Char]’
      Expected type: String
        Actual type: [a0] -> a0"

So it thinks I am giving it the function head, when I would like to give it the output.

How do I fix this?

Thanks in advance,

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Using output of head in data constuctor

Francesco Ariis
Hello Josh

Il 28 giugno 2020 alle 14:36 Josh Friedlander ha scritto:

> I want to create a log parser like this:
>
> module LogAnalysis where
> import Log
>
> parseMessage :: String -> LogMessage
> parseMessage xs
>   | length(words(xs)) < 3 = Unknown xs
>   | notElem(head(words(xs)) ["I", "E", "W"]) = Unknown xs
>   | otherwise = LogMessage Info 3 head(words(xs))
>
> But GHC gives me "• Couldn't match type ‘[a0] -> a0’ with ‘[Char]’
>       Expected type: String
>         Actual type: [a0] -> a0"

I suspect `LogMessage Info 3 head(words(xs))` is the problem. This is
the same as writing

    LogMessage Info 3 head (words xs)

keeping in mind how whitespace and parentheses work in Haskell. You
probably want

    LogMessage Info 3 (head (words xs))

instead.
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Using output of head in data constuctor

Josh Friedlander
Thanks Francesco, that works. I don't quite understand what the issue was, though. Specifically:
- Did the parentheses around (xs) hurt, or were they just redundant?
- Wouldn't the parentheses around (head ...) be binding it as an argument to whatever comes before (in this case, 3)?

On Sun, 28 Jun 2020 at 14:47, Francesco Ariis <[hidden email]> wrote:
Hello Josh

Il 28 giugno 2020 alle 14:36 Josh Friedlander ha scritto:
> I want to create a log parser like this:
>
> module LogAnalysis where
> import Log
>
> parseMessage :: String -> LogMessage
> parseMessage xs
>   | length(words(xs)) < 3 = Unknown xs
>   | notElem(head(words(xs)) ["I", "E", "W"]) = Unknown xs
>   | otherwise = LogMessage Info 3 head(words(xs))
>
> But GHC gives me "• Couldn't match type ‘[a0] -> a0’ with ‘[Char]’
>       Expected type: String
>         Actual type: [a0] -> a0"

I suspect `LogMessage Info 3 head(words(xs))` is the problem. This is
the same as writing

    LogMessage Info 3 head (words xs)

keeping in mind how whitespace and parentheses work in Haskell. You
probably want

    LogMessage Info 3 (head (words xs))

instead.
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Using output of head in data constuctor

Bob Ippolito
Parentheses in Haskell aren’t really related to function application, they are only for grouping. It makes more sense if you avoid using them unless strictly necessary.

In Haskell instead of `f(g(x))` we would write `f (g x)`, and instead of `f(x,g(y),z)` we would write `f x (g y) z`. You could use more parentheses but it would be more confusing, such as `(f)(x)(g(y))(z)`.

On Sun, Jun 28, 2020 at 05:50 Josh Friedlander <[hidden email]> wrote:
Thanks Francesco, that works. I don't quite understand what the issue was, though. Specifically:
- Did the parentheses around (xs) hurt, or were they just redundant?
- Wouldn't the parentheses around (head ...) be binding it as an argument to whatever comes before (in this case, 3)?

On Sun, 28 Jun 2020 at 14:47, Francesco Ariis <[hidden email]> wrote:
Hello Josh

Il 28 giugno 2020 alle 14:36 Josh Friedlander ha scritto:
> I want to create a log parser like this:
>
> module LogAnalysis where
> import Log
>
> parseMessage :: String -> LogMessage
> parseMessage xs
>   | length(words(xs)) < 3 = Unknown xs
>   | notElem(head(words(xs)) ["I", "E", "W"]) = Unknown xs
>   | otherwise = LogMessage Info 3 head(words(xs))
>
> But GHC gives me "• Couldn't match type ‘[a0] -> a0’ with ‘[Char]’
>       Expected type: String
>         Actual type: [a0] -> a0"

I suspect `LogMessage Info 3 head(words(xs))` is the problem. This is
the same as writing

    LogMessage Info 3 head (words xs)

keeping in mind how whitespace and parentheses work in Haskell. You
probably want

    LogMessage Info 3 (head (words xs))

instead.
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners