<commit_before>-----------------------------------------------------------------------------
-- |
-- Module      : Data.Peano
-- Copyright   : (c) <NAME> 2009-2014
-- License     : See the file LICENSE.
--
-- Maintainer  : <NAME> <<EMAIL>>
-- Stability   : experimental
--
-- Peano numbers.
-----------------------------------------------------------------------------

{-# LANGUAGE UnicodeSyntax #-}

module Data.Peano
  ( (∸)
  , int2Nat
  , Nat(Z, S)
  , nat2Int
  )
where

import Control.Monad ( liftM )

import Test.QuickCheck
  ( Arbitrary(arbitrary)
  , oneof
  )

-----------------------------------------------------------------------------
-- From http://byorgey.wordpress.com/2010/11/:
--
-- Note that the auto-derived Ord instance have exactly the right
-- behavior due to the fact that we happened to list the Z constructor
-- first.

-- | Peano natural numbers.
data Nat = Z | S Nat
         deriving (Eq, Ord)

nat2Integer ∷ Nat → Integer
nat2Integer Z     = 0
nat2Integer (S n) = 1 + nat2Integer n

nat2Int ∷ Nat → Int
nat2Int Z     = 0
nat2Int (S n) = 1 + nat2Int n

int2Nat ∷ Int → Nat
int2Nat n | n < 0 = error "int2Nat: negative argument"
int2Nat 0         = Z
int2Nat n         = S $ int2Nat (n - 1)

-- Adapted from http://byorgey.wordpress.com/2010/11/.
instance Num Nat where
  Z   + n = n
  S m + n = S (m + n)

  Z   * _ = Z
  S m * n = n + m * n

  m   - Z   = m
  Z   - S _ = Z
  S m - S n = m - n

  abs n = n

  negate _ = error "negate"

  signum Z     = 0
  signum (S _) = 1

  fromInteger 0 = Z
  fromInteger n = if n < 0
                  then error "fromInteger: negative value"
                  else S (fromInteger (n - 1))

-- | Truncated subtraction.
(∸) ∷ Nat → Nat → Nat
(∸) = (-)

instance Real Nat where
  toRational = toRational . nat2Integer

instance Enum Nat where
  fromEnum = fromEnum . nat2Int

  toEnum 0 = Z
  toEnum n = if n > 0
             then S (toEnum (n - 1))
             else error "toEnum: negative value"

instance Integral Nat where<commit_msg>Fixed Peano instance of Num<commit_after>-----------------------------------------------------------------------------
-- |
-- Module      : Data.Peano
-- Copyright   : (c) <NAME> 2009-2014
-- License     : See the file LICENSE.
--
-- Maintainer  : <NAME> <<EMAIL>>
-- Stability   : experimental
--
-- Peano numbers.
-----------------------------------------------------------------------------

{-# LANGUAGE UnicodeSyntax #-}

module Data.Peano
  ( (∸)
  , int2Nat
  , Nat(Z, S)
  , nat2Int
  )
where

import Control.Monad ( liftM )

import Test.QuickCheck
  ( Arbitrary(arbitrary)
  , oneof
  )

-----------------------------------------------------------------------------
-- From http://byorgey.wordpress.com/2010/11/:
--
-- Note that the auto-derived Ord instance have exactly the right
-- behavior due to the fact that we happened to list the Z constructor
-- first.

-- | Peano natural numbers.
data Nat = Z | S Nat
         deriving (Eq, Ord)

nat2Integer ∷ Nat → Integer
nat2Integer Z     = 0
nat2Integer (S n) = 1 + nat2Integer n

nat2Int ∷ Nat → Int
nat2Int Z     = 0
nat2Int (S n) = 1 + nat2Int n

int2Nat ∷ Int → Nat
int2Nat n | n < 0 = error "int2Nat: negative argument"
int2Nat 0         = Z
int2Nat n         = S $ int2Nat (n - 1)

-- Adapted from http://byorgey.wordpress.com/2010/11/.
instance Num Nat where
  Z   + n = n
  S m + n = S (m + n)

  Z   * _ = Z
  S m * n = n + m * n

  m   - Z   = m
  Z   - S _ = Z
  S m - S n = m - n

  abs n = n

  -- In the @Integral@ class, @div@ is defined via @divMod@ which uses
  -- @negate@. See
  -- http://www.haskell.org/ghc/docs/7.8.2/html/libraries/base-4.7.0.0/src/GHC-Real.html#div.
  negate n = n

  signum Z     = 0
  signum (S _) = 1

  fromInteger 0 = Z
  fromInteger n = if n < 0
                  then error "fromInteger: negative value"
                  else S (fromInteger (n - 1))

-- | Truncated subtraction.
(∸) ∷ Nat → Nat → Nat
(∸) = (-)

instance Real Nat where
  toRational = toRational . nat2Integer

instance Enum Nat where
  fromEnum = fromEnum . nat2Int

  toEnum 0 = Z
  toEnum n = if n > 0
             then S (toEnum (n - 1))
             else error "toEnum: negative value"

instance Integral Nat where
{'fraction_non_alphanumeric': 0.21780528445608188, 'fraction_numerical': 0.026898357533920496, 'mean_word_length': 1.4645161290322581, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5296035', 'n_tokens_mistral': 1514, 'n_tokens_neox': 1380, 'n_words': 487}