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
belgoros
Following the steps described in Chapter 6 of the book, I’m stuck with running the migration as described on page 84: bundle exec sequel...
New
telemachus
Python Testing With Pytest - Chapter 2, warnings for “unregistered custom marks” While running the smoke tests in Chapter 2, I get these...
New
jamis
The following is cross-posted from the original Ray Tracer Challenge forum, from a post by garfieldnate. I’m cross-posting it so that the...
New
JohnS
I can’t setup the Rails source code. This happens in a working directory containing multiple (postgres) Rails apps. With: ruby-3.0.0 s...
New
HarryDeveloper
Hi @venkats, It has been mentioned in the description of ‘Supervisory Job’ title that 2 things as mentioned below result in the same eff...
New
New
leonW
I ran this command after installing the sample application: $ cards add do something --owner Brian And got a file not found error: Fil...
New
s2k
Hi all, currently I wonder how the Tailwind colours work (or don’t work). For example, in app/views/layouts/application.html.erb I have...
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

PragmaticBookshelf
Andy and Dave wrote this influential, classic book to help their clients create better software and rediscover the joy of coding. Almost ...
New
PragmaticBookshelf
Use WebRTC to build web applications that stream media and data in real time directly from one user to another, all in the browser. ...
New
foxtrottwist
A few weeks ago I started using Warp a terminal written in rust. Though in it’s current state of development there are a few caveats (tab...
New
AstonJ
We’ve talked about his book briefly here but it is quickly becoming obsolete - so he’s decided to create a series of 7 podcasts, the firs...
New
PragmaticBookshelf
Rails 7 completely redefines what it means to produce fantastic user experiences and provides a way to achieve all the benefits of single...
New
PragmaticBookshelf
Develop, deploy, and debug BEAM applications using BEAMOps: a new paradigm that focuses on scalability, fault tolerance, and owning each ...
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
AstonJ
This is a very quick guide, you just need to: Download LM Studio: https://lmstudio.ai/ Click on search Type DeepSeek, then select the o...
New
PragmaticBookshelf
Overarching tutorial for Python beginner and intermediate developers that teaches web development with the Flask framework. Miguel Gr...
New
PragmaticBookshelf
This book forgoes the abstract and instead provides concrete examples to help you better leverage the unique properties of Elixir, Erlang...
New

Sub Categories: