jrinaldi

jrinaldi

Effective Haskell: wrong definition of sumOfUniques (page 393 on Kindle)

@RebeccaSkinner

Currently, it is:

sumOfUniques n = ​ foldr (add n) (additiveIdentity n) . unique n

It should be:

sumOfUniques n = ​ foldr add additiveIdentity . unique n

Marked As Solved

jrinaldi

jrinaldi

Hi Rebecca,

Thank you very much for the detailed explanation. Sorry, the example is actually correct.

I was missing the fact that equal and additiveIdentity are actually field selectors. Instead, I thought they were the fields: types a -> a -> Bool and a, respectively. That would have been the case if the Natural a would have been pattern-matched against Natural{..} by enabling the RecordWildCards extension.

Also Liked

RebeccaSkinner

RebeccaSkinner

Author of Effective Haskell

Hi!

Are you seeing an error? I believe this example should be correct. Remember than in example we’re using our own definition of Natural - a record that contains functions that tell us how to do arithmetic:

data Natural a = Natural
{ equal :: a -> a -> Bool
, add : a -> a -> a
, multiply :: a -> a -> a
, additiveIdentity :: a
, multiplicativeIdentity :: a
, displayAsString :: a -> String
}

We’ll call sumOfUniques by giving it some particular definition of natural numbers, for example intNatural or peanoNatural. Here’s an example of how we might call it:

λ sumOfUniques intNatural [1..10]
55

In this example, we’re passing in intNatural, which tells us how to do these operations on Int values. Its’ defined like this:

intNatural :: Natural Int
intNatural = Natural
  { equal = (==)
  , add = (+)
  , multiply = (*)
  , additiveIdentity = 0
  , multiplicativeIdentity = 1
  , displayAsString = show
  }

If we substitute intNatural for nn in our example, we’d end up with something like this:

foldr (add intNatural) (additiveIdentity intNatural) . unique intNatural

You can see here that we’re accessing the functions inside of our Natural record and passing them in as arguments to foldr. If we expaned this out another layer, it’ll make a bit more sense:

-- First, remember that
add intNatural = (+)
additiveIdentity intNatural = 0

-- so
foldr (add intNatural) (additiveIdentity intNatural) . unique intNatural
-- is the same as
foldr (+) 0 . unique intNatural

Later, once we refactor Natural to be a type class instead of a record, we won’t need to explicitly pass around n at all, since that will be part of the constraint in our type class. In that case, we can imagine that our definition would be something like:

sumOfUniques :: Natural n => [n] -> n
sumOfUniques = foldr add additiveIdentity . unique

Where Next?

Popular Pragmatic Bookshelf topics Top

abtin
page 20: … protoc command… I had to additionally run the following go get commands in order to be able to compile protobuf code using go...
New
New
patoncrispy
I’m new to Rust and am using this book to learn more as well as to feed my interest in game dev. I’ve just finished the flappy dragon exa...
New
AndyDavis3416
@noelrappin Running the webpack dev server, I receive the following warning: ERROR in tsconfig.json TS18003: No inputs were found in c...
New
jskubick
I’m under the impression that when the reader gets to page 136 (“View Data with the Database Inspector”), the code SHOULD be able to buil...
New
adamwoolhether
I’m not quite sure what’s going on here, but I’m unable to have to containers successfully complete the Readiness/Liveness checks. I’m im...
New
Keton
When running the program in chapter 8, “Implementing Combat”, the printout Health before attack was never printed so I assumed something ...
New
New
SlowburnAZ
Getting an error when installing the dependencies at the start of this chapter: could not compile dependency :exla, "mix compile" failed...
New
roadbike
From page 13: On Python 3.7, you can install the libraries with pip by running these commands inside a Python venv using Visual Studio ...
New

Other popular topics Top

siddhant3030
I’m thinking of buying a monitor that I can rotate to use as a vertical monitor? Also, I want to know if someone is using it for program...
New
Rainer
My first contact with Erlang was about 2 years ago when I used RabbitMQ, which is written in Erlang, for my job. This made me curious and...
New
PragmaticBookshelf
From finance to artificial intelligence, genetic algorithms are a powerful tool with a wide array of applications. But you don't need an ...
New
AstonJ
There’s a whole world of custom keycaps out there that I didn’t know existed! Check out all of our Keycaps threads here: https://forum....
New
AstonJ
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me. I think the Planck and the Preonic (o...
New
Maartz
Hi folks, I don’t know if I saw this here but, here’s a new programming language, called Roc Reminds me a bit of Elm and thus Haskell. ...
New
PragmaticBookshelf
Build efficient applications that exploit the unique benefits of a pure functional language, learning from an engineer who uses Haskell t...
New
PragmaticBookshelf
Author Spotlight Mike Riley @mriley This month, we turn the spotlight on Mike Riley, author of Portable Python Projects. Mike’s book ...
New
AnfaengerAlex
Hello, I’m a beginner in Android development and I’m facing an issue with my project setup. In my build.gradle.kts file, I have the foll...
New
PragmaticBookshelf
Explore the power of Ash Framework by modeling and building the domain for a real-world web application. Rebecca Le @sevenseacat and ...
New

Sub Categories: