
jrinaldi
Effective Haskell: wrong definition of sumOfUniques (page 393 on Kindle)
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
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
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 n
n 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
Popular Prag Prog topics








Modern front-end development for Rails, second edition - Struggling to get the first chapter to work


Other popular topics










Latest in PragProg
Latest (all)
Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /js
- /rails
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /haskell
- /emacs
- /svelte
- /onivim
- /typescript
- /crystal
- /c-plus-plus
- /tailwind
- /kotlin
- /gleam
- /react
- /flutter
- /elm
- /ocaml
- /vscode
- /opensuse
- /centos
- /ash
- /php
- /deepseek
- /scala
- /zig
- /html
- /debian
- /nixos
- /lisp
- /agda
- /textmate
- /sublime-text
- /react-native
- /kubuntu
- /arch-linux
- /ubuntu
- /revery
- /manjaro
- /spring
- /django
- /diversity
- /lua
- /nodejs
- /slackware
- /julia
- /c
- /neovim