1
votes

I am new Haskell learner, and trying to do count words, but there are errors. how can i change to code and show the result like this

countWords ["friend","she","she"] 
 >[("friend",1),("she",2)

here is code

Prelude Data.List> countWords xs = map(\w -> (head w, length w)) 
 $group $ sort $ words xs
Prelude Data.List> countWords ["hello", "hello", "world"]

:101:13: error: • Couldn't match expected type ‘Char’ with actual type ‘[Char]’ • In the expression: "hello" In the first argument of ‘countWords’, namely ‘["hello", "hello", "world"]’ In the expression: countWords ["hello", "hello", "world"]

:101:22: error: • Couldn't match expected type ‘Char’ with actual type ‘[Char]’ • In the expression: "hello" In the first argument of ‘countWords’, namely ‘["hello", "hello", "world"]’ In the expression: countWords ["hello", "hello", "world"]

:101:31: error: • Couldn't match expected type ‘Char’ with actual type ‘[Char]’ • In the expression: "world" In the first argument of ‘countWords’, namely ‘["hello", "hello", "world"]’ In the expression: countWords ["hello", "hello", "world"]

Thank you

2
words expects a single string, not a list of strings. Are you sure you need words at all? The input seems to be already split into words.chi

2 Answers

3
votes

As @chi said - words :: String -> [String] so either change the input type for your function to a single string of words separated by whitespace, or omit the words part, i.e.

countWords :: [String] -> [(String,Int)]
countWords xs = map (\w -> (head w, length w)) $ group $ sort xs

an example usage for this:

Prelude Data.List> countWords ["hello", "hello", "world"]
> [("hello",2),("world",1)]

or

countWords :: String -> [(String,Int)]
countWords xs = map (\w -> (head w, length w)) $ group $ sort $ words xs

an example usage:

Prelude Data.List> countWords "hello hello world"
> [("hello",2),("world",1)]
2
votes

Let's break this down to a simpler example:

Prelude> xs = ["hello", "hello", "world"]
Prelude> words xs

<interactive>:2:7: error:
    • Couldn't match type ‘[Char]’ with ‘Char’
      Expected type: String
        Actual type: [[Char]]
    • In the first argument of ‘words’, namely ‘xs’
      In the expression: words xs
      In an equation for ‘it’: it = words xs

As you can see, we get a type error at the application of words. Further investigation shows us the problem:

Prelude> :t words
words :: String -> [String]
Prelude> :t xs
xs :: [[Char]]

Here we see the types for words and xs. First, words expects a String as its argument. However, xs type is [[Char]]. Since [Char] is the same as String, xs type can also be given as [String].

Now we see the problem. You are passing a [String] (a list of Strings) to a function which expects a single String.