packages feed

EdisonAPI-1.3.3: src/Data/Edison/Prelude.hs

-- |
--   Module      :  Data.Edison.Prelude
--   Copyright   :  Copyright (c) 1998 Chris Okasaki
--   License     :  BSD3; see COPYRIGHT file for terms and conditions
--
--   Maintainer  :  robdockins AT fastmail DOT fm
--   Stability   :  stable
--   Portability :  GHC, Hugs (MPTC and FD)
--
--   This module is a central depository of common definitions
--   used throughout Edison.

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Data.Edison.Prelude (
-- * Hashing classes
  Hash (..)
, UniqueHash
, ReversibleHash (..)
, Measured (..)
-- * Pure MonadFail
,  runFail_
) where

import Control.Monad.Fail
import Data.Monoid

-- | This class represents hashable objects. If obeys the 
--   following invariant:
--
-- @forall x,y :: a. (x == y) implies (hash x == hash y)@

class Eq a => Hash a where
  hash :: a -> Int


-- | This class represents hashable objects where the hash function
--   is /unique/ (injective).  There are no new methods, just a 
--   stronger invariant:
--
-- @forall x,y :: a. (x == y) iff (hash x == hash y)@

class Hash a => UniqueHash a


-- | This class represents hashable objects where the hash is
--   reversible.
--
-- @forall x :: a. unhash (hash x) == x@
--
--  Note that:
--
-- @hash (unhash i) == i@
--
-- does not necessarily hold because 'unhash' is not necessarily
-- defined for all @i@, only for all @i@ in the range of hash.

class UniqueHash a => ReversibleHash a where
  unhash :: Int -> a


-- | This class represents a quantity that can be measured.  It is
--   calculated by an associative function with a unit (hence the
--   @Monoid@ superclass, and by a function which gives the measurement
--   for an individual item.  Some datastructures are able to speed up
--   the calculation of a measure by caching intermediate values of
--   the computation.
class (Monoid v) => Measured v a | a -> v where
  measure :: a -> v

-- From Agda source code: src/full/Agda/Utils/Fail.hs
-- | A pure MonadFail.
newtype Fail a = Fail { runFail :: Either String a }
  deriving (Functor, Applicative, Monad)

instance MonadFail Fail where
  fail = Fail . Left

runFail_ :: Fail a -> a
runFail_ = either error id . runFail