Nested folds

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

Nested folds

Pietro Grandinetti
Hello,
I have a piece of code to represents Sentences, Paragraphs and the Content of an article. I added functions to count the words, code below. My questions:

1- Are these functions idiomatic?
2- Is this an efficient way to do the computation?
3- In different languages, I could (and would) give the same name `wordCount` to the three functions, because the type of the input would clarify the usage. But here GHC throws an error. What's the most idiomatic way to do this in Haskell?

type Sentence  = String
type Paragraph = [Sentence]
type Content   = [Paragraph]

sentWordCount :: Sentence -> Int
sentWordCount = length . words

parWordCount :: Paragraph -> Int
parWordCount = foldr ((+) . sentWordCount) 0

contWordCount :: Content -> Int
contWordCount = foldr ((+) . parWordCount) 0

I also have two more practical questions on the following two functions:

makeSentence :: String -> Sentence
makeSentence x = x::Sentence

sentCharCount :: Sentence -> Int
sentCharCount x = length $ filter (/= ' ') x

4- About `makeSentence` -- does it make sense to write a function like that just to encapsulate the String type?
5- About `sentCharCount` -- I cannot take the argument x off, the compilator complains. What's the reason?

Thanks,
-P



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

Re: Nested folds

Francesco Ariis
Hello Pietro,

Il 13 dicembre 2020 alle 10:39 Pietro Grandinetti ha scritto:
> Hello,
> I have a piece of code to represents Sentences, Paragraphs and the Content of an article. I added functions to count the words, code below. My questions:
>
> […]
>
> I also have two more practical questions on the following two functions:
>
> makeSentence :: String -> Sentence
> makeSentence x = x::Sentence

You can omit the `:: Sentence` part, since it is specified in the
signature above. You can omit the whole function itself to be fair,
Sentence is a type synonym!

> sentCharCount :: Sentence -> Int
> sentCharCount x = length $ filter (/= ' ') x

You can write this point-free like this

    sentCharCount :: Sentence -> Int
    sentCharCount = length . filter (/= ' ')

In this example you can regard `$` as «evaluate everything on the right
before anything else», so

    length $ filter (/= ' ')
    ^^^^^^   ^^^^^^^^^^^^^^^
      |            |
      |            |
      |            +-- this has type :: [Char] -> [Char]
      |
      +-- length does not work on `[Char] -> [Char]`

`.` instead is appropriate

    λ> :t (.)
    (.) :: (b -> c) -> (a -> b) -> a -> c

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

Re: Nested folds

Pietro Grandinetti
Hello Francesco,

Yes, that helped. However, I believe I shouldn't remove the `makeSentence`. A user of the module is not supposed to know what a `Sentence` is, hence I must provide a function such as `makeSentence`. Right now, its implementation is just a type conversion, but may change later.
This would be my logic in different languages; does it make sense in Haskell?

Do you have any feedback on my questions 1,2 and 3?

Thanks,
-P


From: Beginners <[hidden email]> on behalf of Francesco Ariis <[hidden email]>
Sent: Sunday, December 13, 2020 6:25 PM
To: [hidden email] <[hidden email]>
Subject: Re: [Haskell-beginners] Nested folds
 
Hello Pietro,

Il 13 dicembre 2020 alle 10:39 Pietro Grandinetti ha scritto:
> Hello,
> I have a piece of code to represents Sentences, Paragraphs and the Content of an article. I added functions to count the words, code below. My questions:
>
> […]
>
> I also have two more practical questions on the following two functions:
>
> makeSentence :: String -> Sentence
> makeSentence x = x::Sentence

You can omit the `:: Sentence` part, since it is specified in the
signature above. You can omit the whole function itself to be fair,
Sentence is a type synonym!

> sentCharCount :: Sentence -> Int
> sentCharCount x = length $ filter (/= ' ') x

You can write this point-free like this

    sentCharCount :: Sentence -> Int
    sentCharCount = length . filter (/= ' ')

In this example you can regard `$` as «evaluate everything on the right
before anything else», so

    length $ filter (/= ' ')
    ^^^^^^   ^^^^^^^^^^^^^^^
      |            |
      |            |
      |            +-- this has type :: [Char] -> [Char]
      |
      +-- length does not work on `[Char] -> [Char]`

`.` instead is appropriate

    λ> :t (.)
    (.) :: (b -> c) -> (a -> b) -> a -> c

Does this clear your doubts?
—F
_______________________________________________
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: Nested folds

Francesco Ariis
Il 13 dicembre 2020 alle 19:04 Pietro Grandinetti ha scritto:
> Yes, that helped. However, I believe I shouldn't remove the `makeSentence`.
> A user of the module is not supposed to know what a `Sentence` is, hence I
> must provide a function such as `makeSentence`.

But they will know, a type synonym is just a way to make signatures
prettier/more informative, a program like this

    foo :: String
    foo = "foo"

    k = sentCharCount foo

will _not_ be refused by the compiler. IF and when — in the future — you
decide to use newtype/data then you will get a compiler error (and in turn
would need a constructor with signature `:: String -> Sentence`.

> Do you have any feedback on my questions 1,2 and 3?

The functions are clearly written, there is some duplication because of
the type synonyms (i.e. `parWordCount` and `contWordCount` are the same
function).
Do not worry about it now and revisit the exercise once you start
using `newtype` and `data` + typeclasses
—F

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