Scrapbook-0.4.0: code examples
Copyright© Frank Jung 2020
LicenseGPL-3
Safe HaskellSafe-Inferred
LanguageHaskell2010

RepMax

Description

From Time Traveling In Haskell: How It Works And How To Use It by Daniel Lafe.

Code for what Csongor calls the repMax problem:

Imagine you had a list, and you wanted to replace all the elements of
the list with the largest element, by only passing the list once.

How can we possibly do this in one pass? First, we need to find the maximum element, and only then can we have something to replace the other numbers with! It turns out, though, that we can just expect to have the future value, and all will be well.

In the function repMax takes the list of integers, each of which it must replace with their maximum element. It also takes as an argument the maximum element, as if it had already been computed. It does, however, still compute the intermediate maximum element, in the form of m'. Otherwise, where would the future value even come from?

Thus far, nothing too magical has happened. It’s a little strange to expect the result of the computation to be given to us; it just looks like wishful thinking. The real magic happens in Csongor’s doRepMax function.

Look, in particular, on the line with the where clause. We see that repMax returns the maximum element of the list, largest, and the resulting list xs' consisting only of largest repeated as many times as xs had elements. But what’s curious is the call to repMax itself. It takes as input xs, the list we’re supposed to process and largest, the value that it itself returns.

See also Time travel in Haskell for dummies by Csongor Kiss.

See this for an explanation on how mapAccumR works.

Example

Run doRepMax or foldMax over some lists:

>>> doRepMax [2,3,1,4,5]
[5,5,5,5,5]
>>> doRepMax [-2,-3,-1,-4,-5]
[-1,-1,-1,-1,-1]
Synopsis

Documentation

doRepMax Source #

Arguments

:: Integral a 
=> [a]

input list

-> [a]

list with elements replaced with maximum value

Replace list with maximum value in the list.

foldMax Source #

Arguments

:: Integral a 
=> [a]

list to change

-> [a]

list replaced with maximum element

Fold version of repMax.

Modified to also work with negative values. "Everything's a fold".

repMax Source #

Arguments

:: Integral a 
=> [a]

list to replace

-> a

maximum value used in replacement

-> (a, [a])

maximum and modified list maximum element

Repeat given maximum for entire list.

traverseMax Source #

Arguments

:: (Traversable t, Integral a) 
=> t a

traversable input

-> t a

modified with maximum element

Generalise repMax where input is a Traversable.

Seed value from First of Foldable.

traverseMax' Source #

Arguments

:: (Traversable t, Integral a) 
=> t a

traversable input

-> t a

modified with maximum element

Generalise repMax where input is a Traversable.

Seed maximum value from head of list or 0 if empty.