Chapter�9
Standard Prelude

In this chapter the entire Haskell Prelude is given. It constitutes a specification for the Prelude. Many of the definitions are written with clarity rather than efficiency in mind, and it is not required that the specification be implemented as shown here.

The default method definitions, given with class declarations, constitute a specification only of the default method. They do not constitute a specification of the meaning of the method in all instances. To take one particular example, the default method for enumFrom in class Enum will not work properly for types whose range exceeds that of Int (because fromEnum cannot map all values in the type to distinct Int values).

The Prelude shown here is organized into a root module, Prelude, and three sub-modules, PreludeList, PreludeText, and PreludeIO. This structure is purely presentational. An implementation is not required to use this organisation for the Prelude, nor are these three modules available for import separately. Only the exports of module Prelude are significant.

Some of these modules import Library modules, such as Data.Char, Control.Monad, System.IO, and Numeric. These modules are described fully in Part�II. These imports are not, of course, part of the specification of the Prelude. That is, an implementation is free to import more, or less, of the Library modules, as it pleases.

Primitives that are not definable in Haskell, indicated by names starting with “prim”, are defined in a system dependent manner in module PreludeBuiltin and are not shown here. Instance declarations that simply bind primitives to class methods are omitted. Some of the more verbose instances with obvious functionality have been left out for the sake of brevity.

Declarations for special types such as Integer, or () are included in the Prelude for completeness even though the declaration may be incomplete or syntactically invalid. An ellipsis “...” is often used in places where the remainder of a definition cannot be given in Haskell.

To reduce the occurrence of unexpected ambiguity errors, and to improve efficiency, a number of commonly-used functions over lists use the Int type rather than using a more general numeric type, such as Integral�a or Num�a. These functions are: take, drop, !!, length, splitAt, and replicate. The more general versions are given in the Data.List library, with the prefix “generic”; for example genericLength.

module�Prelude�( �
����module�PreludeList,�module�PreludeText,�module�PreludeIO, �
����Bool(False,�True), �
����Maybe(Nothing,�Just), �
����Either(Left,�Right), �
����Ordering(LT,�EQ,�GT), �
����Char,�String,�Int,�Integer,�Float,�Double,�Rational,�IO,

--������These�built-in�types�are�defined�in�the�Prelude,�but �
--������are�denoted�by�built-in�syntax,�and�cannot�legally �
--������appear�in�an�export�list. �
--��List�type:�[]((:),�[]) �
--��Tuple�types:�(,)((,)),�(,,)((,,)),�etc. �
--��Trivial�type:�()(()) �
--��Functions:�(->) �

����Eq((==),�(/=)), �
����Ord(compare,�(<),�(<=),�(>=),�(>),�max,�min), �
����Enum(succ,�pred,�toEnum,�fromEnum,�enumFrom,�enumFromThen, �
���������enumFromTo,�enumFromThenTo), �
����Bounded(minBound,�maxBound), �
����Num((+),�(-),�(⋆),�negate,�abs,�signum,�fromInteger), �
����Real(toRational), �
����Integral(quot,�rem,�div,�mod,�quotRem,�divMod,�toInteger), �
����Fractional((/),�recip,�fromRational), �
����Floating(pi,�exp,�log,�sqrt,�(⋆⋆),�logBase,�sin,�cos,�tan, �
�������������asin,�acos,�atan,�sinh,�cosh,�tanh,�asinh,�acosh,�atanh), �
����RealFrac(properFraction,�truncate,�round,�ceiling,�floor), �
����RealFloat(floatRadix,�floatDigits,�floatRange,�decodeFloat, �
��������������encodeFloat,�exponent,�significand,�scaleFloat,�isNaN, �
��������������isInfinite,�isDenormalized,�isIEEE,�isNegativeZero,�atan2), �
����Monad((>>=),�(>>),�return,�fail), �
����Functor(fmap), �
����mapM,�mapM_,�sequence,�sequence_,�(=<<), �
����maybe,�either, �
����(&&),�(||),�not,�otherwise, �
����subtract,�even,�odd,�gcd,�lcm,�(^),�(^^), �
����fromIntegral,�realToFrac, �
����fst,�snd,�curry,�uncurry,�id,�const,�(.),�flip,�($),�until, �
����asTypeOf,�error,�undefined, �
����seq,�($!) �
��)�where

import�PreludeBuiltin����������������������--�Contains�all�‘prim'�values �
import�UnicodePrims(�primUnicodeMaxChar�)��--�Unicode�primitives �
import�PreludeList �
import�PreludeText �
import�PreludeIO �
import�Data.Ratio(�Rational�)

infixr�9��. �
infixr�8��^,�^^,�⋆⋆ �
infixl�7��⋆,�/,�‘quot‘,�‘rem‘,�‘div‘,�‘mod‘ �
infixl�6��+,�-

--�The�(:)�operator�is�built-in�syntax,�and�cannot�legally�be�given �
--�a�fixity�declaration;�but�its�fixity�is�given�by: �
--���infixr�5��: �

infix��4��==,�/=,�<,�<=,�>=,�> �
infixr�3��&& �
infixr�2��|| �
infixl�1��>>,�>>= �
infixr�1��=<< �
infixr�0��$,�$!,�‘seq‘

--�Standard�types,�classes,�instances�and�related�functions �

--�Equality�and�Ordered�classes �

class��Eq�a��where �
����(==),�(/=)�::�a�->�a�->�Bool �

��������--�Minimal�complete�definition: �
��������--������(==)�or�(/=) �
����x�/=�y�����=��not�(x�==�y) �
����x�==�y�����=��not�(x�/=�y)

class��(Eq�a)�=>�Ord�a��where �
����compare��������������::�a�->�a�->�Ordering �
����(<),�(<=),�(>=),�(>)�::�a�->�a�->�Bool �
����max,�min�������������::�a�->�a�->�a �

��������--�Minimal�complete�definition: �
��������--������(<=)�or�compare �
��������--�Using�compare�can�be�more�efficient�for�complex�types. �
����compare�x�y �
���������|�x�==�y����=��EQ �
���������|�x�<=�y����=��LT �
���������|�otherwise�=��GT �

����x�<=�y�����������=��compare�x�y�/=�GT �
����x�<��y�����������=��compare�x�y�==�LT �
����x�>=�y�����������=��compare�x�y�/=�LT �
����x�>��y�����������=��compare�x�y�==�GT

--�note�that�(min�x�y,�max�x�y)�=�(x,y)�or�(y,x) �
����max�x�y �
���������|�x�<=�y����=��y �
���������|�otherwise�=��x �
����min�x�y �
���������|�x�<=�y����=��x �
���������|�otherwise�=��y

--�Enumeration�and�Bounded�classes �

class��Enum�a��where �
����succ,�pred�������::�a�->�a �
����toEnum�����������::�Int�->�a �
����fromEnum���������::�a�->�Int �
����enumFrom���������::�a�->�[a]�������������--�[n..] �
����enumFromThen�����::�a�->�a�->�[a]��������--�[n,n'..] �
����enumFromTo�������::�a�->�a�->�[a]��������--�[n..m] �
����enumFromThenTo���::�a�->�a�->�a�->�[a]���--�[n,n'..m] �

��������--�Minimal�complete�definition: �
��������--������toEnum,�fromEnum �
��������-- �
��������--�NOTE:�these�default�methods�only�make�sense�for�types �
��������--�������that�map�injectively�into�Int�using�fromEnum �
��������--�������and�toEnum. �
����succ�������������=��toEnum�.�(+1)�.�fromEnum �
����pred�������������=��toEnum�.�(subtract�1)�.�fromEnum �
����enumFrom�x�������=��map�toEnum�[fromEnum�x�..] �
����enumFromTo�x�y���=��map�toEnum�[fromEnum�x�..�fromEnum�y] �
����enumFromThen�x�y�=��map�toEnum�[fromEnum�x,�fromEnum�y�..] �
����enumFromThenTo�x�y�z�= �
������������������������map�toEnum�[fromEnum�x,�fromEnum�y�..�fromEnum�z]

class��Bounded�a��where �
����minBound���������::�a �
����maxBound���������::�a

--�Numeric�classes �

class��(Eq�a,�Show�a)�=>�Num�a��where �
����(+),�(-),�(⋆)����::�a�->�a�->�a �
����negate�����������::�a�->�a �
����abs,�signum������::�a�->�a �
����fromInteger������::�Integer�->�a �

��������--�Minimal�complete�definition: �
��������--������All,�except�negate�or�(-) �
����x�-�y������������=��x�+�negate�y �
����negate�x���������=��0�-�x

class��(Num�a,�Ord�a)�=>�Real�a��where �
����toRational�������::��a�->�Rational

class��(Real�a,�Enum�a)�=>�Integral�a��where �
����quot,�rem��������::�a�->�a�->�a �
����div,�mod���������::�a�->�a�->�a �
����quotRem,�divMod��::�a�->�a�->�(a,a) �
����toInteger��������::�a�->�Integer �

��������--�Minimal�complete�definition: �
��������--������quotRem,�toInteger �
����n�‘quot‘�d�������=��q��where�(q,r)�=�quotRem�n�d �
����n�‘rem‘�d��������=��r��where�(q,r)�=�quotRem�n�d �
����n�‘div‘�d��������=��q��where�(q,r)�=�divMod�n�d �
����n�‘mod‘�d��������=��r��where�(q,r)�=�divMod�n�d �
����divMod�n�d�������=��if�signum�r�==�-�signum�d�then�(q-1,�r+d)�else�qr �
������������������������where�qr@(q,r)�=�quotRem�n�d

class��(Num�a)�=>�Fractional�a��where �
����(/)��������������::�a�->�a�->�a �
����recip������������::�a�->�a �
����fromRational�����::�Rational�->�a �

��������--�Minimal�complete�definition: �
��������--������fromRational�and�(recip�or�(/)) �
����recip�x����������=��1�/�x �
����x�/�y������������=��x�⋆�recip�y

class��(Fractional�a)�=>�Floating�a��where �
����pi������������������::�a �
����exp,�log,�sqrt������::�a�->�a �
����(⋆⋆),�logBase�������::�a�->�a�->�a �
����sin,�cos,�tan�������::�a�->�a �
����asin,�acos,�atan����::�a�->�a �
����sinh,�cosh,�tanh����::�a�->�a �
����asinh,�acosh,�atanh�::�a�->�a �

��������--�Minimal�complete�definition: �
��������--������pi,�exp,�log,�sin,�cos,�sinh,�cosh �
��������--������asin,�acos,�atan �
��������--������asinh,�acosh,�atanh �
����x�⋆⋆�y�����������=��exp�(log�x�⋆�y) �
����logBase�x�y������=��log�y�/�log�x �
����sqrt�x�����������=��x�⋆⋆�0.5 �
����tan��x�����������=��sin��x�/�cos��x �
����tanh�x�����������=��sinh�x�/�cosh�x

class��(Real�a,�Fractional�a)�=>�RealFrac�a��where �
����properFraction���::�(Integral�b)�=>�a�->�(b,a) �
����truncate,�round��::�(Integral�b)�=>�a�->�b �
����ceiling,�floor���::�(Integral�b)�=>�a�->�b �

��������--�Minimal�complete�definition: �
��������--������properFraction �
����truncate�x�������=��m��where�(m,_)�=�properFraction�x �

����round�x����������=��let�(n,r)�=�properFraction�x �
����������������������������m�����=�if�r�<�0�then�n�-�1�else�n�+�1 �
��������������������������in�case�signum�(abs�r�-�0.5)�of �
��������������������������������-1�->�n �
��������������������������������0��->�if�even�n�then�n�else�m �
��������������������������������1��->�m �

����ceiling�x��������=��if�r�>�0�then�n�+�1�else�n �
������������������������where�(n,r)�=�properFraction�x �

����floor�x����������=��if�r�<�0�then�n�-�1�else�n �
������������������������where�(n,r)�=�properFraction�x

class��(RealFrac�a,�Floating�a)�=>�RealFloat�a��where �
����floatRadix�������::�a�->�Integer �
����floatDigits������::�a�->�Int �
����floatRange�������::�a�->�(Int,Int) �
����decodeFloat������::�a�->�(Integer,Int) �
����encodeFloat������::�Integer�->�Int�->�a �
����exponent���������::�a�->�Int �
����significand������::�a�->�a �
����scaleFloat�������::�Int�->�a�->�a �
����isNaN,�isInfinite,�isDenormalized,�isNegativeZero,�isIEEE �
���������������������::�a�->�Bool �
����atan2������������::�a�->�a�->�a �

��������--�Minimal�complete�definition: �
��������--������All�except�exponent,�significand, �
��������--�����������������scaleFloat,�atan2 �
����exponent�x�������=��if�m�==�0�then�0�else�n�+�floatDigits�x �
������������������������where�(m,n)�=�decodeFloat�x �

����significand�x����=��encodeFloat�m�(-�floatDigits�x) �
������������������������where�(m,_)�=�decodeFloat�x �

����scaleFloat�k�x���=��encodeFloat�m�(n+k) �
������������������������where�(m,n)�=�decodeFloat�x �

����atan2�y�x �
������|�x>0�����������=��atan�(y/x) �
������|�x==0�&&�y>0���=��pi/2 �
������|�x<0��&&�y>0���=��pi�+�atan�(y/x) �
������|(x<=0�&&�y<0)��|| �
�������(x<0�&&�isNegativeZero�y)�|| �
�������(isNegativeZero�x�&&�isNegativeZero�y) �
����������������������=�-atan2�(-y)�x �
������|�y==0�&&�(x<0�||�isNegativeZero�x) �
����������������������=��pi����--�must�be�after�the�previous�test�on�zero�y �
������|�x==0�&&�y==0��=��y�����--�must�be�after�the�other�double�zero�tests �
������|�otherwise�����=��x�+�y�--�x�or�y�is�a�NaN,�return�a�NaN�(via�+)

--�Numeric�functions �

subtract���������::�(Num�a)�=>�a�->�a�->�a �
subtract���������=��flip�(-)

even,�odd��������::�(Integral�a)�=>�a�->�Bool �
even�n�����������=��n�‘rem‘�2�==�0 �
odd��������������=��not�.�even

gcd��������������::�(Integral�a)�=>�a�->�a�->�a �
gcd�0�0����������=��error�"Prelude.gcd:�gcd�0�0�is�undefined" �
gcd�x�y����������=��gcd'�(abs�x)�(abs�y) �
��������������������where�gcd'�x�0��=��x �
��������������������������gcd'�x�y��=��gcd'�y�(x�‘rem‘�y)

lcm��������������::�(Integral�a)�=>�a�->�a�->�a �
lcm�_�0����������=��0 �
lcm�0�_����������=��0 �
lcm�x�y����������=��abs�((x�‘quot‘�(gcd�x�y))�⋆�y)

(^)��������������::�(Num�a,�Integral�b)�=>�a�->�b�->�a �
x�^�0������������=��1 �
x�^�n�|�n�>�0����=��f�x�(n-1)�x �
��������������������where�f�_�0�y�=�y �
��������������������������f�x�n�y�=�g�x�n��where �
������������������������������������g�x�n�|�even�n��=�g�(x⋆x)�(n�‘quot‘�2) �
������������������������������������������|�otherwise�=�f�x�(n-1)�(x⋆y) �
_�^�_������������=�error�"Prelude.^:�negative�exponent"

(^^)�������������::�(Fractional�a,�Integral�b)�=>�a�->�b�->�a �
x�^^�n�����������=��if�n�>=�0�then�x^n�else�recip�(x^(-n))

fromIntegral�����::�(Integral�a,�Num�b)�=>�a�->�b �
fromIntegral�����=��fromInteger�.�toInteger

realToFrac�����::�(Real�a,�Fractional�b)�=>�a�->�b �
realToFrac������=��fromRational�.�toRational

--�Monadic�classes �

class��Functor�f��where �
����fmap��������������::�(a�->�b)�->�f�a�->�f�b

class��Monad�m��where �
����(>>=)��::�m�a�->�(a�->�m�b)�->�m�b �
����(>>)���::�m�a�->�m�b�->�m�b �
����return�::�a�->�m�a �
����fail���::�String�->�m�a �

��������--�Minimal�complete�definition: �
��������--������(>>=),�return �
����m�>>�k��=��m�>>=�\_�->�k �
����fail�s��=�error�s

sequence�������::�Monad�m�=>�[m�a]�->�m�[a] �
sequence�������=��foldr�mcons�(return�[]) �
��������������������where�mcons�p�q�=�p�>>=�\x�->�q�>>=�\y�->�return�(x:y)

sequence_������::�Monad�m�=>�[m�a]�->�m�() �
sequence_������=��foldr�(>>)�(return�())

--�The�xxxM�functions�take�list�arguments,�but�lift�the�function�or �
--�list�element�to�a�monad�type �
mapM�������������::�Monad�m�=>�(a�->�m�b)�->�[a]�->�m�[b] �
mapM�f�as��������=��sequence�(map�f�as)

mapM_������������::�Monad�m�=>�(a�->�m�b)�->�[a]�->�m�() �
mapM_�f�as�������=��sequence_�(map�f�as)

(=<<)������������::�Monad�m�=>�(a�->�m�b)�->�m�a�->�m�b �
f�=<<�x����������=��x�>>=�f

--�Trivial�type �

data��()��=��()��deriving�(Eq,�Ord,�Enum,�Bounded) �
��������--�Not�legal�Haskell;�for�illustration�only

--�Function�type �

--�identity�function �
id���������������::�a�->�a �
id�x�������������=��x

--�constant�function �
const������������::�a�->�b�->�a �
const�x�_��������=��x

--�function�composition �
(.)��������������::�(b�->�c)�->�(a�->�b)�->�a�->�c �
f�.�g������������=��\�x�->�f�(g�x)

--�flip�f��takes�its�(first)�two�arguments�in�the�reverse�order�of�f. �
flip�������������::�(a�->�b�->�c)�->�b�->�a�->�c �
flip�f�x�y�������=��f�y�x

seq�::�a�->�b�->�b �
seq�=�...�������--�Primitive

--�right-associating�infix�application�operators �
--�(useful�in�continuation-passing�style) �
($),�($!)�::�(a�->�b)�->�a�->�b �
f�$��x����=��f�x �
f�$!�x����=��x�‘seq‘�f�x

--�Boolean�type �

data��Bool��=��False�|�True�����deriving�(Eq,�Ord,�Enum,�Read,�Show,�Bounded)

--�Boolean�functions �

(&&),�(||)�������::�Bool�->�Bool�->�Bool �
True��&&�x�������=��x �
False�&&�_�������=��False �
True��||�_�������=��True �
False�||�x�������=��x

not��������������::�Bool�->�Bool �
not�True���������=��False �
not�False��������=��True

otherwise��������::�Bool �
otherwise��������=��True

--�Character�type �

data�Char�=�...�'a'�|�'b'�...�--�Unicode�values

instance��Eq�Char��where �
����c�==�c'����������=��fromEnum�c�==�fromEnum�c'

instance��Ord�Char��where �
����c�<=�c'����������=��fromEnum�c�<=�fromEnum�c'

instance��Enum�Char��where �
����toEnum������������=�primIntToChar �
����fromEnum����������=�primCharToInt �
����enumFrom�c��������=�map�toEnum�[fromEnum�c�..�fromEnum�(maxBound::Char)] �
����enumFromThen�c�c'�=�map�toEnum�[fromEnum�c,�fromEnum�c'�..�fromEnum�lastChar] �
����������������������where�lastChar�::�Char �
����������������������������lastChar�|�c'�<�c����=�minBound �
�������������������������������������|�otherwise�=�maxBound

instance��Bounded�Char��where �
����minBound��=��'\0' �
����maxBound��=��primUnicodeMaxChar

type��String�=�[Char]

--�Maybe�type �

data��Maybe�a��=��Nothing�|�Just�a������deriving�(Eq,�Ord,�Read,�Show)

maybe��������������::�b�->�(a�->�b)�->�Maybe�a�->�b �
maybe�n�f�Nothing��=��n �
maybe�n�f�(Just�x)�=��f�x

instance��Functor�Maybe��where �
����fmap�f�Nothing����=��Nothing �
����fmap�f�(Just�x)���=��Just�(f�x)

instance��Monad�Maybe��where �
����(Just�x)�>>=�k���=��k�x �
����Nothing��>>=�k���=��Nothing �
����return�����������=��Just �
����fail�s�����������=��Nothing

--�Either�type �

data��Either�a�b��=��Left�a�|�Right�b���deriving�(Eq,�Ord,�Read,�Show)

either���������������::�(a�->�c)�->�(b�->�c)�->�Either�a�b�->�c �
either�f�g�(Left�x)��=��f�x �
either�f�g�(Right�y)�=��g�y

--�IO�type �

data�IO�a�=�...���������--�abstract

instance��Functor�IO�where �
���fmap�f�x�����������=��x�>>=�(return�.�f)

instance�Monad�IO�where �
���(>>=)��=�... �
���return�=�... �
���fail�s�=�ioError�(userError�s)

--�Ordering�type �

data��Ordering��=��LT�|�EQ�|�GT �
����������deriving�(Eq,�Ord,�Enum,�Read,�Show,�Bounded)

--�Standard�numeric�types.��The�data�declarations�for�these�types�cannot �
--�be�expressed�directly�in�Haskell�since�the�constructor�lists�would�be �
--�far�too�large. �

data��Int��=��minBound�...�-1�|�0�|�1�...�maxBound �
instance��Eq�������Int��where�... �
instance��Ord������Int��where�... �
instance��Num������Int��where�... �
instance��Real�����Int��where�... �
instance��Integral�Int��where�... �
instance��Enum�����Int��where�... �
instance��Bounded��Int��where�...

data��Integer��=��...�-1�|�0�|�1�... �
instance��Eq�������Integer��where�... �
instance��Ord������Integer��where�... �
instance��Num������Integer��where�... �
instance��Real�����Integer��where�... �
instance��Integral�Integer��where�... �
instance��Enum�����Integer��where�...

data��Float �
instance��Eq���������Float��where�... �
instance��Ord��������Float��where�... �
instance��Num��������Float��where�... �
instance��Real�������Float��where�... �
instance��Fractional�Float��where�... �
instance��Floating���Float��where�... �
instance��RealFrac���Float��where�... �
instance��RealFloat��Float��where�...

data��Double �
instance��Eq���������Double��where�... �
instance��Ord��������Double��where�... �
instance��Num��������Double��where�... �
instance��Real�������Double��where�... �
instance��Fractional�Double��where�... �
instance��Floating���Double��where�... �
instance��RealFrac���Double��where�... �
instance��RealFloat��Double��where�...

--�The�Enum�instances�for�Floats�and�Doubles�are�slightly�unusual. �
--�The�‘toEnum'�function�truncates�numbers�to�Int.��The�definitions �
--�of�enumFrom�and�enumFromThen�allow�floats�to�be�used�in�arithmetic �
--�series:�[0,0.1�..�0.95].��However,�roundoff�errors�make�these�somewhat �
--�dubious.��This�example�may�have�either�10�or�11�elements,�depending�on �
--�how�0.1�is�represented. �

instance��Enum�Float��where �
����succ�x�����������=��x+1 �
����pred�x�����������=��x-1 �
����toEnum�����������=��fromIntegral �
����fromEnum���������=��fromInteger�.�truncate���--�may�overflow �
����enumFrom���������=��numericEnumFrom �
����enumFromThen�����=��numericEnumFromThen �
����enumFromTo�������=��numericEnumFromTo �
����enumFromThenTo���=��numericEnumFromThenTo

instance��Enum�Double��where �
����succ�x�����������=��x+1 �
����pred�x�����������=��x-1 �
����toEnum�����������=��fromIntegral �
����fromEnum���������=��fromInteger�.�truncate���--�may�overflow �
����enumFrom���������=��numericEnumFrom �
����enumFromThen�����=��numericEnumFromThen �
����enumFromTo�������=��numericEnumFromTo �
����enumFromThenTo���=��numericEnumFromThenTo

numericEnumFrom���������::�(Fractional�a)�=>�a�->�[a] �
numericEnumFromThen�����::�(Fractional�a)�=>�a�->�a�->�[a] �
numericEnumFromTo�������::�(Fractional�a,�Ord�a)�=>�a�->�a�->�[a] �
numericEnumFromThenTo���::�(Fractional�a,�Ord�a)�=>�a�->�a�->�a�->�[a] �
numericEnumFrom���������=��iterate�(+1) �
numericEnumFromThen�n�m�=��iterate�(+(m-n))�n �
numericEnumFromTo�n�m���=��takeWhile�(<=�m+1/2)�(numericEnumFrom�n) �
numericEnumFromThenTo�n�n'�m�=�takeWhile�p�(numericEnumFromThen�n�n') �
�����������������������������where �
�������������������������������p�|�n'�>=�n���=�(<=�m�+�(n'-n)/2) �
���������������������������������|�otherwise�=�(>=�m�+�(n'-n)/2)

--�Lists �

data��[a]��=��[]�|�a�:�[a]��deriving�(Eq,�Ord) �
��������--�Not�legal�Haskell;�for�illustration�only

instance�Functor�[]�where �
����fmap�=�map

instance��Monad�[]��where �
����m�>>=�k����������=�concat�(map�k�m) �
����return�x���������=�[x] �
����fail�s�����������=�[]

--�Tuples �

data��(a,b)���=��(a,b)����deriving�(Eq,�Ord,�Bounded) �
data��(a,b,c)�=��(a,b,c)��deriving�(Eq,�Ord,�Bounded) �
��������--�Not�legal�Haskell;�for�illustration�only

--�component�projections�for�pairs: �
--�(NB:�not�provided�for�triples,�quadruples,�etc.) �
fst��������������::�(a,b)�->�a �
fst�(x,y)��������=��x

snd��������������::�(a,b)�->�b �
snd�(x,y)��������=��y

--�curry�converts�an�uncurried�function�to�a�curried�function; �
--�uncurry�converts�a�curried�function�to�a�function�on�pairs. �
curry������������::�((a,�b)�->�c)�->�a�->�b�->�c �
curry�f�x�y������=��f�(x,�y)

uncurry����������::�(a�->�b�->�c)�->�((a,�b)�->�c) �
uncurry�f�p������=��f�(fst�p)�(snd�p)

--�Misc�functions �

--�until�p�f��yields�the�result�of�applying�f�until�p�holds. �
until������������::�(a�->�Bool)�->�(a�->�a)�->�a�->�a �
until�p�f�x �
�����|�p�x�������=��x �
�����|�otherwise�=��until�p�f�(f�x)

--�asTypeOf�is�a�type-restricted�version�of�const.��It�is�usually�used �
--�as�an�infix�operator,�and�its�typing�forces�its�first�argument �
--�(which�is�usually�overloaded)�to�have�the�same�type�as�the�second. �
asTypeOf���������::�a�->�a�->�a �
asTypeOf���������=��const

--�error�stops�execution�and�displays�an�error�message �

error������������::�String�->�a �
error������������=��primError

--�It�is�expected�that�compilers�will�recognize�this�and�insert�error �
--�messages�that�are�more�appropriate�to�the�context�in�which�undefined �
--�appears. �

undefined��������::�a �
undefined��������=��error�"Prelude.undefined"

9.1 Prelude PreludeList

--�Standard�list�functions �

module�PreludeList�( �
����map,�(++),�filter,�concat,�concatMap, �
����head,�last,�tail,�init,�null,�length,�(!!), �
����foldl,�foldl1,�scanl,�scanl1,�foldr,�foldr1,�scanr,�scanr1, �
����iterate,�repeat,�replicate,�cycle, �
����take,�drop,�splitAt,�takeWhile,�dropWhile,�span,�break, �
����lines,�words,�unlines,�unwords,�reverse,�and,�or, �
����any,�all,�elem,�notElem,�lookup, �
����sum,�product,�maximum,�minimum, �
����zip,�zip3,�zipWith,�zipWith3,�unzip,�unzip3) �
��where

import�qualified�Data.Char(isSpace)

infixl�9��!! �
infixr�5��++ �
infix��4��‘elem‘,�‘notElem‘

--�Map�and�append �
map�::�(a�->�b)�->�[a]�->�[b] �
map�f�[]�����=�[] �
map�f�(x:xs)�=�f�x�:�map�f�xs

(++)�::�[a]�->�[a]�->�[a] �
[]�����++�ys�=�ys �
(x:xs)�++�ys�=�x�:�(xs�++�ys)

filter�::�(a�->�Bool)�->�[a]�->�[a] �
filter�p�[]�����������������=�[] �
filter�p�(x:xs)�|�p�x�������=�x�:�filter�p�xs �
����������������|�otherwise�=�filter�p�xs

concat�::�[[a]]�->�[a] �
concat�xss�=�foldr�(++)�[]�xss

concatMap�::�(a�->�[b])�->�[a]�->�[b] �
concatMap�f�=�concat�.�map�f

--�head�and�tail�extract�the�first�element�and�remaining�elements, �
--�respectively,�of�a�list,�which�must�be�non-empty.��last�and�init �
--�are�the�dual�functions�working�from�the�end�of�a�finite�list, �
--�rather�than�the�beginning. �

head�������������::�[a]�->�a �
head�(x:_)�������=��x �
head�[]����������=��error�"Prelude.head:�empty�list"

tail�������������::�[a]�->�[a] �
tail�(_:xs)������=��xs �
tail�[]����������=��error�"Prelude.tail:�empty�list"

last�������������::�[a]�->�a �
last�[x]���������=��x �
last�(_:xs)������=��last�xs �
last�[]����������=��error�"Prelude.last:�empty�list"

init�������������::�[a]�->�[a] �
init�[x]���������=��[] �
init�(x:xs)������=��x�:�init�xs �
init�[]����������=��error�"Prelude.init:�empty�list"

null�������������::�[a]�->�Bool �
null�[]����������=��True �
null�(_:_)�������=��False

--�length�returns�the�length�of�a�finite�list�as�an�Int. �
length�����������::�[a]�->�Int �
length�[]��������=��0 �
length�(_:l)�����=��1�+�length�l

--�List�index�(subscript)�operator,�0-origin �
(!!)����������������::�[a]�->�Int�->�a �
xs�����!!�n�|�n�<�0�=��error�"Prelude.!!:�negative�index" �
[]�����!!�_���������=��error�"Prelude.!!:�index�too�large" �
(x:_)��!!�0���������=��x �
(_:xs)�!!�n���������=��xs�!!�(n-1)

--�foldl,�applied�to�a�binary�operator,�a�starting�value�(typically�the �
--�left-identity�of�the�operator),�and�a�list,�reduces�the�list�using �
--�the�binary�operator,�from�left�to�right: �
--��foldl�f�z�[x1,�x2,�...,�xn]�==�(...((z�‘f‘�x1)�‘f‘�x2)�‘f‘...)�‘f‘�xn �
--�foldl1�is�a�variant�that�has�no�starting�value�argument,�and��thus�must �
--�be�applied�to�non-empty�lists.��scanl�is�similar�to�foldl,�but�returns �
--�a�list�of�successive�reduced�values�from�the�left: �
--������scanl�f�z�[x1,�x2,�...]�==�[z,�z�‘f‘�x1,�(z�‘f‘�x1)�‘f‘�x2,�...] �
--�Note�that��last�(scanl�f�z�xs)�==�foldl�f�z�xs. �
--�scanl1�is�similar,�again�without�the�starting�element: �
--������scanl1�f�[x1,�x2,�...]�==�[x1,�x1�‘f‘�x2,�...] �

foldl������������::�(a�->�b�->�a)�->�a�->�[b]�->�a �
foldl�f�z�[]�����=��z �
foldl�f�z�(x:xs)�=��foldl�f�(f�z�x)�xs

foldl1�����������::�(a�->�a�->�a)�->�[a]�->�a �
foldl1�f�(x:xs)��=��foldl�f�x�xs �
foldl1�_�[]������=��error�"Prelude.foldl1:�empty�list"

scanl������������::�(a�->�b�->�a)�->�a�->�[b]�->�[a] �
scanl�f�q�xs�����=��q�:�(case�xs�of �
����������������������������[]���->�[] �
����������������������������x:xs�->�scanl�f�(f�q�x)�xs)

scanl1�����������::�(a�->�a�->�a)�->�[a]�->�[a] �
scanl1�f�(x:xs)��=��scanl�f�x�xs �
scanl1�_�[]������=��[]

--�foldr,�foldr1,�scanr,�and�scanr1�are�the�right-to-left�duals�of�the �
--�above�functions. �

foldr������������::�(a�->�b�->�b)�->�b�->�[a]�->�b �
foldr�f�z�[]�����=��z �
foldr�f�z�(x:xs)�=��f�x�(foldr�f�z�xs)

foldr1�����������::�(a�->�a�->�a)�->�[a]�->�a �
foldr1�f�[x]�����=��x �
foldr1�f�(x:xs)��=��f�x�(foldr1�f�xs) �
foldr1�_�[]������=��error�"Prelude.foldr1:�empty�list"

scanr�������������::�(a�->�b�->�b)�->�b�->�[a]�->�[b] �
scanr�f�q0�[]�����=��[q0] �
scanr�f�q0�(x:xs)�=��f�x�q�:�qs �
���������������������where�qs@(q:_)�=�scanr�f�q0�xs�

scanr1����������::�(a�->�a�->�a)�->�[a]�->�[a] �
scanr1�f�[]�����=��[] �
scanr1�f�[x]����=��[x] �
scanr1�f�(x:xs)�=��f�x�q�:�qs �
�������������������where�qs@(q:_)�=�scanr1�f�xs�

--�iterate�f�x�returns�an�infinite�list�of�repeated�applications�of�f�to�x: �
--�iterate�f�x�==�[x,�f�x,�f�(f�x),�...] �
iterate����������::�(a�->�a)�->�a�->�[a] �
iterate�f�x������=��x�:�iterate�f�(f�x)

--�repeat�x�is�an�infinite�list,�with�x�the�value�of�every�element. �
repeat�����������::�a�->�[a] �
repeat�x���������=��xs�where�xs�=�x:xs

--�replicate�n�x�is�a�list�of�length�n�with�x�the�value�of�every�element �
replicate��������::�Int�->�a�->�[a] �
replicate�n�x����=��take�n�(repeat�x)

--�cycle�ties�a�finite�list�into�a�circular�one,�or�equivalently, �
--�the�infinite�repetition�of�the�original�list.��It�is�the�identity �
--�on�infinite�lists. �

cycle������������::�[a]�->�[a] �
cycle�[]���������=��error�"Prelude.cycle:�empty�list" �
cycle�xs���������=��xs'�where�xs'�=�xs�++�xs'

--�take�n,�applied�to�a�list�xs,�returns�the�prefix�of�xs�of�length�n, �
--�or�xs�itself�if�n�>�length�xs.��drop�n�xs�returns�the�suffix�of�xs �
--�after�the�first�n�elements,�or�[]�if�n�>�length�xs.��splitAt�n�xs �
--�is�equivalent�to�(take�n�xs,�drop�n�xs). �

take�������������������::�Int�->�[a]�->�[a] �
take�n�_������|�n�<=�0�=��[] �
take�_�[]��������������=��[] �
take�n�(x:xs)����������=��x�:�take�(n-1)�xs

drop�������������������::�Int�->�[a]�->�[a] �
drop�n�xs�����|�n�<=�0�=��xs �
drop�_�[]��������������=��[] �
drop�n�(_:xs)����������=��drop�(n-1)�xs

splitAt������������������::�Int�->�[a]�->�([a],[a]) �
splitAt�n�xs�������������=��(take�n�xs,�drop�n�xs)

--�takeWhile,�applied�to�a�predicate�p�and�a�list�xs,�returns�the�longest �
--�prefix�(possibly�empty)�of�xs�of�elements�that�satisfy�p.��dropWhile�p�xs �
--�returns�the�remaining�suffix.��span�p�xs�is�equivalent�to �
--�(takeWhile�p�xs,�dropWhile�p�xs),�while�break�p�uses�the�negation�of�p. �

takeWhile���������������::�(a�->�Bool)�->�[a]�->�[a] �
takeWhile�p�[]����������=��[] �
takeWhile�p�(x:xs) �
������������|�p�x�������=��x�:�takeWhile�p�xs �
������������|�otherwise�=��[]

dropWhile���������������::�(a�->�Bool)�->�[a]�->�[a] �
dropWhile�p�[]����������=��[] �
dropWhile�p�xs@(x:xs') �
������������|�p�x�������=��dropWhile�p�xs' �
������������|�otherwise�=��xs

span,�break�������������::�(a�->�Bool)�->�[a]�->�([a],[a]) �
span�p�[]������������=�([],[]) �
span�p�xs@(x:xs') �
������������|�p�x�������=��(x:ys,zs) �
������������|�otherwise�=��([],xs) �
���������������������������where�(ys,zs)�=�span�p�xs'

break�p�����������������=��span�(not�.�p)

--�lines�breaks�a�string�up�into�a�list�of�strings�at�newline�characters. �
--�The�resulting�strings�do�not�contain�newlines.��Similary,�words �
--�breaks�a�string�up�into�a�list�of�words,�which�were�delimited�by �
--�white�space.��unlines�and�unwords�are�the�inverse�operations. �
--�unlines�joins�lines�with�terminating�newlines,�and�unwords�joins �
--�words�with�separating�spaces. �

lines������������::�String�->�[String] �
lines�""���������=��[] �
lines�s����������=��let�(l,�s')�=�break�(==�'\n')�s �
����������������������in��l�:�case�s'�of �
��������������������������������[]������->�[] �
��������������������������������(_:s'')�->�lines�s''

words������������::�String�->�[String] �
words�s����������=��case�dropWhile�Char.isSpace�s�of �
����������������������""�->�[] �
����������������������s'�->�w�:�words�s'' �
����������������������������where�(w,�s'')�=�break�Char.isSpace�s'

unlines����������::�[String]�->�String �
unlines����������=��concatMap�(++�"\n")

unwords����������::�[String]�->�String �
unwords�[]�������=��"" �
unwords�ws�������=��foldr1�(\w�s�->�w�++�'�':s)�ws

--�reverse�xs�returns�the�elements�of�xs�in�reverse�order.��xs�must�be�finite. �
reverse����������::�[a]�->�[a] �
reverse����������=��foldl�(flip�(:))�[]

--�and�returns�the�conjunction�of�a�Boolean�list.��For�the�result�to�be �
--�True,�the�list�must�be�finite;�False,�however,�results�from�a�False �
--�value�at�a�finite�index�of�a�finite�or�infinite�list.��or�is�the �
--�disjunctive�dual�of�and. �
and,�or����������::�[Bool]�->�Bool �
and��������������=��foldr�(&&)�True �
or���������������=��foldr�(||)�False

--�Applied�to�a�predicate�and�a�list,�any�determines�if�any�element �
--�of�the�list�satisfies�the�predicate.��Similarly,�for�all. �
any,�all���������::�(a�->�Bool)�->�[a]�->�Bool �
any�p������������=��or�.�map�p �
all�p������������=��and�.�map�p

--�elem�is�the�list�membership�predicate,�usually�written�in�infix�form, �
--�e.g.,�x�‘elem‘�xs.��notElem�is�the�negation. �
elem,�notElem����::�(Eq�a)�=>�a�->�[a]�->�Bool �
elem�x�����������=��any�(==�x) �
notElem�x��������=��all�(/=�x)

--�lookup�key�assocs�looks�up�a�key�in�an�association�list. �
lookup�����������::�(Eq�a)�=>�a�->�[(a,b)]�->�Maybe�b �
lookup�key�[]����=��Nothing �
lookup�key�((x,y):xys) �
����|�key�==�x���=��Just�y �
����|�otherwise��=��lookup�key�xys

--�sum�and�product�compute�the�sum�or�product�of�a�finite�list�of�numbers. �
sum,�product�����::�(Num�a)�=>�[a]�->�a �
sum��������������=��foldl�(+)�0 �
product����������=��foldl�(⋆)�1

--�maximum�and�minimum�return�the�maximum�or�minimum�value�from�a�list, �
--�which�must�be�non-empty,�finite,�and�of�an�ordered�type. �
maximum,�minimum�::�(Ord�a)�=>�[a]�->�a �
maximum�[]�������=��error�"Prelude.maximum:�empty�list" �
maximum�xs�������=��foldl1�max�xs

minimum�[]�������=��error�"Prelude.minimum:�empty�list" �
minimum�xs�������=��foldl1�min�xs

--�zip�takes�two�lists�and�returns�a�list�of�corresponding�pairs.��If�one �
--�input�list�is�short,�excess�elements�of�the�longer�list�are�discarded. �
--�zip3�takes�three�lists�and�returns�a�list�of�triples.��Zips�for�larger �
--�tuples�are�in�the�List�library �

zip��������������::�[a]�->�[b]�->�[(a,b)] �
zip��������������=��zipWith�(,)

zip3�������������::�[a]�->�[b]�->�[c]�->�[(a,b,c)] �
zip3�������������=��zipWith3�(,,)

--�The�zipWith�family�generalises�the�zip�family�by�zipping�with�the �
--�function�given�as�the�first�argument,�instead�of�a�tupling�function. �
--�For�example,�zipWith�(+)�is�applied�to�two�lists�to�produce�the�list �
--�of�corresponding�sums. �

zipWith����������::�(a->b->c)�->�[a]->[b]->[c] �
zipWith�z�(a:as)�(b:bs) �
�����������������=��z�a�b�:�zipWith�z�as�bs �
zipWith�_�_�_����=��[]

zipWith3���������::�(a->b->c->d)�->�[a]->[b]->[c]->[d] �
zipWith3�z�(a:as)�(b:bs)�(c:cs) �
�����������������=��z�a�b�c�:�zipWith3�z�as�bs�cs �
zipWith3�_�_�_�_�=��[]

--�unzip�transforms�a�list�of�pairs�into�a�pair�of�lists. �

unzip������������::�[(a,b)]�->�([a],[b]) �
unzip������������=��foldr�(\(a,b)�~(as,bs)�->�(a:as,b:bs))�([],[])

unzip3�����������::�[(a,b,c)]�->�([a],[b],[c]) �
unzip3�����������=��foldr�(\(a,b,c)�~(as,bs,cs)�->�(a:as,b:bs,c:cs)) �
��������������������������([],[],[])

9.2 Prelude PreludeText

module�PreludeText�( �
����ReadS,�ShowS, �
����Read(readsPrec,�readList), �
����Show(showsPrec,�show,�showList), �
����reads,�shows,�read,�lex, �
����showChar,�showString,�readParen,�showParen�)�where

--�The�instances�of�Read�and�Show�for �
--������Bool,�Maybe,�Either,�Ordering �
--�are�done�via�"deriving"�clauses�in�Prelude.hs �

import�Data.Char(isSpace,�isAlpha,�isDigit,�isAlphaNum, �
�����������������showLitChar,�readLitChar,�lexLitChar)

import�Numeric(showSigned,�showInt,�readSigned,�readDec,�showFloat, �
���������������readFloat,�lexDigits)

type��ReadS�a��=�String�->�[(a,String)] �
type��ShowS����=�String�->�String

class��Read�a��where �
����readsPrec��������::�Int�->�ReadS�a �
����readList���������::�ReadS�[a] �

��������--�Minimal�complete�definition: �
��������--������readsPrec �
����readList���������=�readParen�False�(\r�->�[pr�|�("[",s)��<-�lex�r, �
����������������������������������������������������pr�������<-�readl�s]) �
�����������������������where�readl��s�=�[([],t)���|�("]",t)��<-�lex�s]�++ �
����������������������������������������[(x:xs,u)�|�(x,t)����<-�reads�s, �
����������������������������������������������������(xs,u)���<-�readl'�t] �
�����������������������������readl'�s�=�[([],t)���|�("]",t)��<-�lex�s]�++ �
����������������������������������������[(x:xs,v)�|�(",",t)��<-�lex�s, �
����������������������������������������������������(x,u)����<-�reads�t, �
����������������������������������������������������(xs,v)���<-�readl'�u]

class��Show�a��where �
����showsPrec��������::�Int�->�a�->�ShowS �
����show�������������::�a�->�String �
����showList���������::�[a]�->�ShowS �

��������--�Mimimal�complete�definition: �
��������--������show�or�showsPrec �
����showsPrec�_�x�s���=�show�x�++�s �

����show�x������������=�showsPrec�0�x�"" �

����showList�[]�������=�showString�"[]" �
����showList�(x:xs)���=�showChar�'['�.�shows�x�.�showl�xs �
������������������������where�showl�[]�����=�showChar�']' �
������������������������������showl�(x:xs)�=�showChar�','�.�shows�x�. �
���������������������������������������������showl�xs

reads������������::�(Read�a)�=>�ReadS�a �
reads������������=��readsPrec�0

shows������������::�(Show�a)�=>�a�->�ShowS �
shows������������=��showsPrec�0

read�������������::�(Read�a)�=>�String�->�a �
read�s�����������=��case�[x�|�(x,t)�<-�reads�s,�("","")�<-�lex�t]�of �
�������������������������[x]�->�x �
�������������������������[]��->�error�"Prelude.read:�no�parse" �
�������������������������_���->�error�"Prelude.read:�ambiguous�parse"

showChar���������::�Char�->�ShowS �
showChar���������=��(:)

showString�������::�String�->�ShowS �
showString�������=��(++)

showParen��������::�Bool�->�ShowS�->�ShowS �
showParen�b�p����=��if�b�then�showChar�'('�.�p�.�showChar�')'�else�p

readParen��������::�Bool�->�ReadS�a�->�ReadS�a �
readParen�b�g����=��if�b�then�mandatory�else�optional �
��������������������where�optional�r��=�g�r�++�mandatory�r �
��������������������������mandatory�r�=�[(x,u)�|�("(",s)�<-�lex�r, �
�������������������������������������������������(x,t)���<-�optional�s, �
�������������������������������������������������(")",u)�<-�lex�t����]

--�This�lexer�is�not�completely�faithful�to�the�Haskell�lexical�syntax. �
--�Current�limitations: �
--����Qualified�names�are�not�handled�properly �
--����Octal�and�hexidecimal�numerics�are�not�recognized�as�a�single�token �
--����Comments�are�not�treated�properly �

lex��������������::�ReadS�String �
lex�""�����������=��[("","")] �
lex�(c:s) �
���|�isSpace�c���=��lex�(dropWhile�isSpace�s) �
lex�('\'':s)�����=��[('\'':ch++"'",�t)�|�(ch,'\'':t)��<-�lexLitChar�s, �
�����������������������������������������ch�/=�"'"�] �
lex�('"':s)������=��[('"':str,�t)������|�(str,t)�<-�lexString�s] �
��������������������where �
��������������������lexString�('"':s)�=�[("\"",s)] �
��������������������lexString�s�=�[(ch++str,�u) �
�����������������������������������������|�(ch,t)��<-�lexStrItem�s, �
�������������������������������������������(str,u)�<-�lexString�t��] �

��������������������lexStrItem�('\\':'&':s)�=��[("\\&",s)] �
��������������������lexStrItem�('\\':c:s)�|�isSpace�c �
�������������������������������������������=��[("\\&",t)�| �
�����������������������������������������������'\\':t�<- �
���������������������������������������������������[dropWhile�isSpace�s]] �
��������������������lexStrItem�s�����������=��lexLitChar�s

lex�(c:s)�|�isSingle�c�=�[([c],s)] �
����������|�isSym�c����=�[(c:sym,t)�������|�(sym,t)�<-�[span�isSym�s]] �
����������|�isAlpha�c��=�[(c:nam,t)�������|�(nam,t)�<-�[span�isIdChar�s]] �
����������|�isDigit�c��=�[(c:ds++fe,t)����|�(ds,s)��<-�[span�isDigit�s], �
��������������������������������������������(fe,t)��<-�lexFracExp�s�����] �
����������|�otherwise��=�[]����--�bad�character �
�������������where �
��������������isSingle�c�=��c�‘elem‘�",;()[]{}_‘" �
��������������isSym�c����=��c�‘elem‘�"!@#$%&⋆+./<=>?\\^|:-~" �
��������������isIdChar�c�=��isAlphaNum�c�||�c�‘elem‘�"_'" �

��������������lexFracExp�('.':c:cs)�|�isDigit�c �
����������������������������=�[('.':ds++e,u)�|�(ds,t)�<-�lexDigits�(c:cs), �
�����������������������������������������������(e,u)��<-�lexExp�t] �
��������������lexFracExp�s��=�lexExp�s �

��������������lexExp�(e:s)�|�e�‘elem‘�"eE" �
�����������������������=�[(e:c:ds,u)�|�(c:t)��<-�[s],�c�‘elem‘�"+-", �
�������������������������������������������������(ds,u)�<-�lexDigits�t]�++ �
�������������������������[(e:ds,t)���|�(ds,t)�<-�lexDigits�s] �
��������������lexExp�s�=�[("",s)]

instance��Show�Int��where �
����showsPrec�n�=�showsPrec�n�.�toInteger �
��������--�Converting�to�Integer�avoids �
��������--�possible�difficulty�with�minInt

instance��Read�Int��where �
��readsPrec�p�r�=�[(fromInteger�i,�t)�|�(i,t)�<-�readsPrec�p�r] �
��������--�Reading�at�the�Integer�type�avoids �
��������--�possible�difficulty�with�minInt

instance��Show�Integer��where �
����showsPrec�����������=�showSigned�showInt

instance��Read�Integer��where �
����readsPrec�p���������=�readSigned�readDec

instance��Show�Float��where �
����showsPrec�p���������=�showFloat

instance��Read�Float��where �
����readsPrec�p���������=�readSigned�readFloat

instance��Show�Double��where �
����showsPrec�p���������=�showFloat

instance��Read�Double��where �
����readsPrec�p���������=�readSigned�readFloat

instance��Show�()��where �
����showsPrec�p�()�=�showString�"()"

instance�Read�()�where �
����readsPrec�p����=�readParen�False �
����������������������������(\r�->�[((),t)�|�("(",s)�<-�lex�r, �
���������������������������������������������(")",t)�<-�lex�s�]�) �
instance��Show�Char��where �
����showsPrec�p�'\''�=�showString�"'\\''" �
����showsPrec�p�c����=�showChar�'\''�.�showLitChar�c�.�showChar�'\'' �

����showList�cs�=�showChar�'"'�.�showl�cs �
�����������������where�showl�""�������=�showChar�'"' �
�����������������������showl�('"':cs)�=�showString�"\\\""�.�showl�cs �
�����������������������showl�(c:cs)���=�showLitChar�c�.�showl�cs

instance��Read�Char��where �
����readsPrec�p������=�readParen�False �
����������������������������(\r�->�[(c,t)�|�('\'':s,t)<-�lex�r, �
��������������������������������������������(c,"\'")��<-�readLitChar�s]) �

����readList�=�readParen�False�(\r�->�[(l,t)�|�('"':s,�t)�<-�lex�r, �
�����������������������������������������������(l,_)������<-�readl�s�]) �
��������where�readl�('"':s)������=�[("",s)] �
��������������readl�('\\':'&':s)�=�readl�s �
��������������readl�s������������=�[(c:cs,u)�|�(c�,t)�<-�readLitChar�s, �
�����������������������������������������������(cs,u)�<-�readl�t�������]

instance��(Show�a)�=>�Show�[a]��where �
����showsPrec�p������=�showList

instance��(Read�a)�=>�Read�[a]��where �
����readsPrec�p������=�readList

--�Tuples �

instance��(Show�a,�Show�b)�=>�Show�(a,b)��where �
����showsPrec�p�(x,y)�=�showChar�'('�.�shows�x�.�showChar�','�. �
���������������������������������������shows�y�.�showChar�')'

instance��(Read�a,�Read�b)�=>�Read�(a,b)��where �
����readsPrec�p�������=�readParen�False �
����������������������������(\r�->�[((x,y),�w)�|�("(",s)�<-�lex�r, �
�������������������������������������������������(x,t)���<-�reads�s, �
�������������������������������������������������(",",u)�<-�lex�t, �
�������������������������������������������������(y,v)���<-�reads�u, �
�������������������������������������������������(")",w)�<-�lex�v�]�)

--�Other�tuples�have�similar�Read�and�Show�instances �

9.3 Prelude PreludeIO

module�PreludeIO�( �
����FilePath,�IOError,�ioError,�userError,�catch, �
����putChar,�putStr,�putStrLn,�print, �
����getChar,�getLine,�getContents,�interact, �
����readFile,�writeFile,�appendFile,�readIO,�readLn �
��)�where

import�PreludeBuiltin

type��FilePath�=�String

data�IOError����--�The�internals�of�this�type�are�system�dependent

instance��Show�IOError��where�... �
instance��Eq�IOError��where�...

ioError����::��IOError�->�IO�a �
ioError����=���primIOError

userError��::��String�->�IOError �
userError��=���primUserError

catch������::��IO�a�->�(IOError�->�IO�a)�->�IO�a �
catch������=���primCatch

putChar����::�Char�->�IO�() �
putChar����=��primPutChar

putStr�����::�String�->�IO�() �
putStr�s���=��mapM_�putChar�s

putStrLn���::�String�->�IO�() �
putStrLn�s�=��do�putStr�s �
�����������������putStr�"\n"

print������::�Show�a�=>�a�->�IO�() �
print�x����=��putStrLn�(show�x)

getChar����::�IO�Char �
getChar����=��primGetChar

getLine����::�IO�String �
getLine����=��do�c�<-�getChar �
�����������������if�c�==�'\n'�then�return�""�else �
��������������������do�s�<-�getLine �
�����������������������return�(c:s)

getContents�::�IO�String �
getContents�=��primGetContents

interact����::��(String�->�String)�->�IO�() �
--�The�hSetBuffering�ensures�the�expected�interactive�behaviour �
interact�f��=��do�hSetBuffering�stdin��NoBuffering �
������������������hSetBuffering�stdout�NoBuffering �
������������������s�<-�getContents �
������������������putStr�(f�s)

readFile���::�FilePath�->�IO�String �
readFile���=��primReadFile

writeFile��::�FilePath�->�String�->�IO�() �
writeFile��=��primWriteFile

appendFile�::�FilePath�->�String�->�IO�() �
appendFile�=��primAppendFile �

��--�raises�an�exception�instead�of�an�error �
readIO���::�Read�a�=>�String�->�IO�a �
readIO�s�=��case�[x�|�(x,t)�<-�reads�s,�("","")�<-�lex�t]�of �
��������������[x]�->�return�x �
��������������[]��->�ioError�(userError�"Prelude.readIO:�no�parse") �
��������������_���->�ioError�(userError�"Prelude.readIO:�ambiguous�parse")

readLn�::�Read�a�=>�IO�a �
readLn�=��do�l�<-�getLine �
�������������r�<-�readIO�l �
�������������return�r