liveBook · Manning

Natural

As explained in Learn Haskell by Example

Natural is an arbitrary-precision nonnegative integer type in Haskell.

Natural is a Haskell type for nonnegative integers, imported from Numeric.Natural. It fits values whose meaning excludes negatives, such as a musical octave number. Unlike an enormous enumeration of every possible note and octave, a note can combine a finite name with a Natural octave. section 10.4.1

Listing 10.14 Types for chromatic notes
module Composition.Pitch where

...

import Numeric.Natural (Natural)    #1

...

data ChromaticName = A | As | B | C | Cs | D | Ds | E | F | Fs | G | Gs   #2
  deriving (Show, Eq)                   #3

data Chromatic
  = Chromatic ChromaticName Natural    #4
  deriving (Show, Eq)   #5

A chromatic note separates its name from its octave: ChromaticName lists the twelve names, while Natural records the nonnegative octave. section 10.4.1

This separation makes helper constructors concise: a, as, and the other note-name functions accept a Natural rather than requiring a constructor for every named note in every octave. To calculate pitch, the octave is converted with fromIntegral, then combined with the named semitone offset; the resulting semitone value may be negative even though the octave cannot. section 10.4.1 section 10.4.1

Natural can also be the integral component of exact rational note lengths. Defining Notelength as Ratio Natural permits values such as whole, half, quarter, eighth, and sixteenth, and lets dotted-note and tuplet functions take a nonnegative count. section 10.4.2 section 10.4.2

Listing 10.16 Conversion from chromatic notes to semitones and frequency
module Composition.Notelength where

import Data.Ratio (Ratio, (%))       #1
import Numeric.Natural (Natural)        #2

type Notelength = Ratio Natural     #3

whole :: Notelength       #4
whole = 1 % 1

half :: Notelength       #4
half = 1 % 2

quarter :: Notelength    #4
quarter = 1 % 4

eighth :: Notelength     #4
eighth = 1 % 8

sixteenth :: Notelength    #4
sixteenth = 1 % 16

Ratio Natural gives named note lengths as exact fractions, with Natural supplying the numerator and denominator type. section 10.4.2

Use Natural for a nonnegative musical count

A chromatic pitch may be constructed with a named helper such as a 4, then converted to frequency. For durations, dotted (1 % 2 :: Notelength) evaluates to 3 % 4, while triplet (1 % 2 :: Notelength) evaluates to 1 % 3. section 10.4.1 section 10.4.2

Nonnegative meaning is not the same as safe arithmetic. Natural has a Num instance, so subtraction is allowed syntactically; if a calculation would become negative, it throws an exception. Choose Natural for values that should never go below zero, but account for subtraction before relying on it. section 10.4.2

How Learn Haskell by Example covers it

How deep it goes
Defines Natural as nonnegative integers, demonstrates two representations, and warns about subtraction exceptions without detailing its implementation.
Examples
Uses chromatic octave constructors, frequency conversion, fractional note lengths, dotted notes, and triplets.
What it assumes
Introduces Natural through musical data modeling while relying on Haskell data declarations, imports, and numeric type classes.
What you can do after
Apply it via Numeric.Natural to encode nonnegative octaves, rhythmic counts, and exact Ratio Natural note lengths.
How it connects
Connects Natural to Chromatic notes, Ratio, Notelength, semitones, dotted notes, and tuplets.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.