Sunteți pe pagina 1din 62

LsLrucLuras de uaLos.

Crados en lngenlerla lnformuca, del Soware y de CompuLadores


L1Sl lnformuca
unlversldad de Mlaga

!ose L. Callardo, lranclsco Cuuerrez, ablo Lpez, 8las C. 8ulz
upLo. Lengua[es y Clenclas de la CompuLacln
unlversldad de Mlaga
! rogramacln lunclonal
! rogramacln lmperauva !" rogramacln lunclonal
! lunclones puras e lmpuras
! venLa[as de la rogramacln lunclonal
! lnLroduccln a Paskell
! ldenucadores
! 1lpos bslcos
! uenlclones de funclones. Apllcaclones
! Cperadores, precedencla y asoclauvldad
! Lvaluacln de expreslones
! lnLroduccln a CulckCheck
! 1uplas
! ollmorsmo y sobrecarga
! Lcuaclones condlclonales y expreslones
! lunclones denldas parclalmenLe
! uenlclones locales
! Cperadores !" lunclones
2
! Los cmpuLos manlpulan varlables muLables
! LsLas varlables muLables represenLan la memorla o el
esLado del compuLador
! Los algorlLmos modlcan las varlables hasLa obLener el
resulLado deseado
3
int factorial(int n) {
int i, p = 1;
for(i=1; i<=n; i++)
p = p * i;
return p;
}
Las varlables l y p son
alLeradas duranLe la
e[ecucln
hup://en.wlklpedla.org/wlkl/lmperauve_programmlng
! un esulo de programacln basado en cmpuLos a Lraves
de funclones maLemucas (o puras) :
hup://en.wlklpedla.org/wlkl/luncuonal_programmlng
! un programa es una funcln
! 1oma daLos a Lraves de sus argumenLos
! 8eallza clculos con esLos daLos a Lraves de expreslones
! uevuelve nuevos daLos (resulLados del cmpuLo)
! } nada cambla !
! no exlsLe el concepLo de varlable muLable uplco de la
programacln lmperauva
4
funcln
(programa)
daLos
argumenLos
nuevos daLos
resulLado
! una funcln maLemuca slempre devuelve el mlsmo
resulLado para los mlsmos valores de sus
argumenLos:
# = $ f (x) = f (y) (Regla de Leibniz)
! LsLo conduce a la propledad de Lransparencla
referenclal:
una mlsma expresln denoLa slempre el mlsmo valor, sea
cual sea el punLo del programa o el conLexLo en que
aparezca.
! Slmpllca el razonamlenLo sobre las propledades de
los programas (en parucular, la correccln)
! odemos 'calcular' con programas al lgual que en
maLemucas 'calculamos' con expreslones
3
hup://en.wlklpedla.org/wlkl/ure_funcuon
! un e[emplo de funcln pura:
! nice(5) slempre devuelve 35
! Sl x = y enLonces nice(x) = nice(y) "
6
int nice(int n) {
return n*n+10;
}
! La slgulenLe no es una funcln pura:
! La prlmera llamada weird(5) devuelve 6
! La segunda llamada weird(5) devuelve 7
! ara el mlsmo valor del argumenLo weird
devuelve dlferenLes resulLados #

7
int state = 0;

int weird(int n) {
state += 1;
return n+state;
}
! La slgulenLe Lampoco es una funcln pura
(maLemuca):
int getchar (void);
! Cada llamada puede devolver un valor dlsunLo

8
! La programacln funclonal conslsLe en escrlblr
programas (funclones) comblnando oLras
funclones
! Ln los lengua[es funclonales puros:
! SolamenLe podemos denlr funclones puras
! Se sausface la Lransparencla referenclal "
Mlranda, Clean, "#$%&'', .
! Ln los lengua[es funclonales lmpuros:
! Se permlLe denlr funclones lmpuras #
ML, l#, Scheme, .
9
! Cpumlzacln: el compllador puede reallzar
Lransformaclones sosucadas con ob[eLo de opumlzar el
comporLamlenLo
! aralellsmo: parLes de una expresln pueden evaluarse en
cualquler orden sln alLerar el resulLado, lncluso varlos
procesadores pueden lnLervenlr en la evaluacln de la
mlsma expresln.
! La rogramacln lunclonal ura es lnLrlnsecamenLe paralela "
! La rogramacln lmperauva es lnLrlnsecamenLe secuenclal #

! Memolzauon: los resulLados producldos por las llamadas a
una funcln pueden ser reuullzados (recordados) en
suceslvas llamadas con los mlsmos valores de los
argumenLos

10
! noLacln prxlma a la maLemuca:
! [ x^2+y^2 | x <- [1..20], y <- [1..20], par x ]
! 1lpos y lengua[es fuerLemenLe uplcados:
! LsLos lengua[es son fuerLemenLe uplcados
! un upo es un con[unLo de daLos que comparLen
algunas caracLerlsucas.
! 1lplcar es slnnlmo de claslcar. Se usa una noLacln
Lamblen cercana a la maLemuca:
! 1 :: lnLeger 1 Z
! suc :: lnLeger -> lnLeger suc Z -> Z

11
! un Lengua[e lunclonal uro esLndar
! rlnclpales caracLerlsucas:
! ureza funclonal
! 1lplcacln esLuca
! erezoso (Lazy)

12
www.haskell.org
! Paskell 'dlsungue' mayusculas de mlnusculas (case sensluve) !

! Los ldenucadores (nombres) de funclones y argumenLos:
! ueben empezar con una leLra mlnuscula o el carcLer _ (underscore) y esLe
puede lr seguldo de leLras (mayusculas o mlnusculas), dlglLos, uldes (') o _
! L[emplos vlldos de ldenucadores:
f f' f2 x _uno factorial rbol toList p1_gcd
! L[emplos no vlldos:
Function 2f f!y
! Los nombres de upos deben empezar con una leLra mayuscula
Int, Integer, Bool, Float, Double, eLc.
! Los nombres de operadores:
! ueden conLener uno o varlos slmbolos
! Ll prlmero no puede ser dos-punLos (:)
! L[emplos vlldos:
+ * - !! <= ==> +:


13

! Int un subcon[unLo acoLado de los numeros enLeros
! operaclones rpldas, poslbllldad de %!&'(%) o *+,&'(%)
! Prelude> max8ound :: lnL
2147483647
! Prelude> (max8ound :: lnL) + 1
-2147483648
! Prelude> mln8ound :: lnL
-2147483648
! Prelude> (10000000000 :: lnL ) * 1000000000
! -1981284332
14
2^31 -1

! Integer el con[unLo 'compleLo' de los enLeros

! Prelude> (10000000000 :: lnLeger ) * 1000000000
! 10000000000000000000

! Float subcon[unLo de los reales en slmple preclsln
2 -3.5 1.5E10
! Prelude> (1e-43 :: lloaL)
! 1.0e-43
! Prelude> (1e-43 :: lloaL) / 2
! 0.0
! Double subcon[unLo de los reales en doble preclsln
! Prelude> (1e-300 :: uouble) / 2
! 3.0e-301
13
! Bool uene solamenLe dos valores: True y
False
! con[uncln lglca (and):
(&&) :: Bool -> Bool -> Bool
! dlsyuncln lglca (or):
(||) :: Bool -> Bool -> Bool
! negacln lglca:
not :: Bool -> Bool

(1 < 3) (x >=y) || noL (prlmo y)
Pay condlcln de corLoclrculLo
16
hup://en.wlklpedla.org/wlkl/Ceorge_8oole
! Char esL formado por los 236 caracLeres
esLandarlzados (y ms, unlcode characLer seL) :
'a', 'b', .,'z', 'A','B', .,'Z',
'0','1', ., '9', '+','?', .
! Muchas 'funclones sobre' caracLeres aparecen
denldas en el mdulo o llbrerla Data.Char:
import Data.Char
g, g' :: Char -> Char
g x = chr (ord x + ord 'A' - ord 'a')
g' x = toUpper x

17
! Paskell usa noLacln parclallzada (currled)
! lnLroduclda por
Moses Schnnkel (1889-1942)
y popularlzada por
Paskell Curry (1900-1982)
! ara denlr una apllcacln:
! Lscrlblmos el ldenucador de la funcln y a
conunuacln los argumenLos separados por espaclos
! Ll uso de parenLesls ser necesarlo para agrupar
Lermlnos compuesLos y modlcar el efecLo de las
prlorldades de las operaclones
18
hup://en.wlklpedla.org/wlkl/Currylng
19
twice :: Integer -> Integer
twice x = x + x
square :: Integer -> Integer
square x = x * x

pythagoras :: Integer -> Integer -> Integer
pythagoras x y = square x + square y

nombre de
la funcin
argumento
resultado
toma un
entero
devuelve un
entero
toma dos enteros
y devuelve un
entero
20
square :: Integer -> Integer
square x = x*x
pythagoras :: Integer -> Integer -> Integer
pythagoras x y = square x + square y
square 10 $ 10*10 $ 100

square 5 + 1 $ 5*5 + 1 $ $ 26

square (5 + 1) $ square 6 $ $ 36


phytagoras 10 6 $ square 10 + square 6
$ $ 136

phytagoras 10 (twice 3)
$ square 10 + square (twice 3)
$ $ 136

square solo se aplica
una vez al 5
square se aplica a la suma
5 + 1.
Los parntesis son
necesarios
phytagoras se aplica
a los dos argumentos
El segundo argumento es
compuesto y necesita
parntesis
! Las funclones con varlos argumenLos producen
funclones parclales sln van seguldas de menos
argumenLos :
! 1amblen podemos lnclulr denlclones parclales
en un programa:
g :: lnLeger -> lnLeger
g = pyLhagoras 4
21
Main> () *+),#-./#$ 0
pyLhagoras 4 :: lnLeger -> lnLeger
Main> (*+),#-./#$ 0 1 2
17
22

una expresln condlclonal, como cualquler oLra
expresln, puede formar parLe del cuerpo de una
funcln:

maxInteger :: Integer -> Integer -> Integer

maxInteger x y = if x >= y then x else y







Main> () 3#456)&-&/ 0
maxlnLeger 4 :: lnLeger -> lnLeger
Main> 3#456)&-&/ 0 27
17
23

Ll cuerpo de una funcln puede conLener a la funcln que dene

fact :: Int -> Int

fact n = if n==0 then 1 else n * fact (n-1) -- recursividad

La eleccln del upo Int (subcon[unLo nlLo) causar problemas:

fact 16 $ 2004189184 fact 17 $ -288522240

Ll problema se resuelve Lomando lnLeger (una absLraccln del
con[unLo 'compleLo' de los enLeros)

factorial:: Integer -> Integer

factorial n = if n==0 then 1 else n * factorial (n-1)

factorial 17 $ 355687428096000
! CPC denoLa el ./0"1%) 20"3&// 4%567/&', un
compllador de alLa calldad para Paskell
! CPCl denoLa el ./0"1%) 20"3&// 4%567/&'
8+9&'6'&9&':
! Con el uso del bucle :&0,;<!0/;='7+9 podemos e[ecuLar
programas Paskell
! CPC y CPCl esLn dlsponlbles para las plaLaformas
ms populares: lndows, Llnux y CS
! Ln la pglna web de la aslgnaLura aparecen
lnsLrucclones de lnsLalacln
24
! uos enLornos para CPCl
23
! Ll operador unarlo - es el unlco operador unarlo
slmbllco pre[o:
! -1 -(1+2) $ -3
! Ll resLo de operadores slmbllcos blnarlos se usan
dlrecLamenLe en forma ln[a:
! 1+2 $ 3
! 1 + 2*3 $ 1 + 6
! (1+2)*3 $ 3*3
! 1 + -2 $ ='&>&,&+>& 60'"7+1 &''%'
! 1 + (-2) $ -1


26
89:&' ;*&/#<./ */&<&=69<.
Mxlma precedencla 10 Apllcacln de una funcln
9 . !!
8 ^ ^^ **
7 * /
6 + -
3 : ++
4 == /= < <= > >=
3 &&
2 ||
1 >> >>= =<<
Mlnlma precedencla 0 $ $!
27
La aplicacin de una
funcin tiene prioridad
mxima
La multiplicacin tiene
mayor nivel de
precedencia que la suma
! LsLa propledad permlLe resolver la amblgedad
en ausencla de parenLesls:
! Sl # asocla a la lzqulerda:
x
1
# x
2
# x
n
= (((x
1
# x
2
) # x
3
) # x
n
)

! Sl # asocla a la derecha:
x
1
# x
2
# x
n
= (x
1
# (x
n-2
#(x
n-1
# x
n
)))
! Sl # no es asoclauvo:
x
1
# x
2
# x
n

28

ERROR: los parntesis
son necesarios





L[emplos:

10 3 3 $ ((10 3) 3)

2 ^ 3 ^ 4 $ (2 ^ (3 ^ 4))

1 < 3 < 4



>$.?9#@:9<#< ;*&/#<./
uerecha ^$^^$** : && || $$$!
lzqulerda *$/ +$- >>$>>=$=<<
no asoclauvo ==$/=$<$<=$>=$>
29

Expresin errnea

Use parntesis si
desconoce la forma
de la asociatividad
! Son dlferenLes concepLos que no deben ser
confundldos

! La asoclauvldad es un aLrlbuLo slnLcuco de un
operador en un lengua[e de programacln
! Ll operador # verlca la propledad asoclauva en
senudo maLemuco sl sausface:
x, y, z . (x y) z = x (y z)
! La propledad asoclauva Lamblen es lnLeresanLe
compuLaclonalmenLe:
! ara evaluar x y z se parenuzar de acuerdo con el
menor cosLe compuLaclonal.

30
Nivel de precedencia




infix 4 ~= -- Comprueba si dos reales son
-- aproximadamente iguales

(~=) :: Double -> Double -> Bool
x ~= y = abs (x-y) < epsilon
$ where epsilon = 1/1000

infix = no asociativo.
infixl = asociativo a izda
infixr = asociativo a dcha
El identificador del
operador debe
aparecer entre
parntesis en una
declaracin de tipo
31
Main> (1/3) ~= 0.33
False
Main> (1/3) ~= 0.333
True
! 1oda funcln de dos argumenLos cuyo ldenucador sea llLeral
puede ser uullzada en forma ln[a &+>&''?+,%/% enLre acenLos
graves ()

Prelude> div 10 2
5
Prelude> 10 `div` 2
5
Prelude> 10 div 2
TYPE ERROR ...
Prelude> max 10 (max 3 15)
15
Prelude> 10 `max` 3 `max` 15
15
notacin prefija
Error
32
Si la funcin es asociativa
no son necesarios los
parntesis
forma infija
! 8eclprocamenLe, cualquler operador slmbllco puede uullzarse en
forma pre[a &+>&''?+,%/% enLre parenLesls

Prelude> 10 + 2
12
Prelude> (+) 10 2
12
Prelude> + 10 2
SYNTAX ERROR
33
forma prefija
forma infija
Error
twice :: Integer -> Integer
twice x = x + x


$$ twice 10
$ {- definicin de twice -}
$$10 + 10
$ {- aritmtica -}
$$20
34
! 8edex ('&,*>7@/& &#6'&""7%+): parLe de una expresln que puede
ser slmpllcada
! 8educcln: proceso de reescrlLura de un redex. Cada reduccln es
un paso de cmpuLo
! lorma normal : expresln sln redexes
33
$$ twice 10
$ {- definicin -}
$$10 + 10
$ {- aritmtica -}
$$20

redex
reduccin
20 es una forma
normal
twice :: Integer -> Integer
twice x = x + x

$$ twice (10+2)
$ {- aritmtica -}
$$twice 12
$ {- definicin -}
$ $12 + 12
$ {- aritmtica -}
$$ 24

36
Orden Aplicativo
Se reduce el redex ms interno y ms
a la izquierda.
Los argumentos son evaluados antes
que la funcin

Pros
Los argumentos compuestos se
evalan una sola vez

Contras
Pueden realizarse reducciones
innecesarias.
Puede no conducir a la forma normal
(no es normalizante)
second :: Integer -> Integer -> Integer
second x y = y

$$ second (div 1 0) 2
$ {- aritmtica -}
$$ Exception: divide by zero

37
Orden Aplicativo
Se reduce el redex ms interno y ms
a la izquierda.
Los argumentos son evaluados antes
que la funcin

Pros
Los argumentos compuestos se
evaluan una sola vez

Contras
Pueden realizarse reducciones
innecesarias.
Puede no conducir a la forma normal
(no es normalizante)

twice :: Integer -> Integer
twice x = x + x

$$$ twice (10+2)
$ {- definicin -}
$$(10+2) + (10+2)
$ {- aritmtica -}
$$12 + (10+2)
$ {- aritmtica -}
$$12 + 12
$ {- aritmtica -}
$$24


38
Orden Normal
Se reduce el redex ms externo y
ms a la izquierda.
La funcin es aplicada antes de
evaluar sus argumentos

Pros
Slo se evalan las expresiones
necesarias.
Siempre conduce a la forma normal si
sta existe (normalizante)

Contras
Puede repetirse la evaluacin de un
argumento compuesto
second :: Integer -> Integer -> Integer
second x y = y

$$ second (div 1 0) 2
$ {- definicin de second -}
$$ 2

39
Orden Normal
Se reduce el redex ms externo y
ms a la izquierda.
La funcin es aplicada antes de
evaluar sus argumentos

Pros
Slo se evalan las expresiones
necesarias.
Siempre conduce a la forma normal si
sta existe (normalizante)

Contras
Puede repetirse la evaluacin de un
argumento compuesto

! Paskell usa &:#'A#?9B6 *&/&C.$# D!"#$1 :
! Comblna las venLa[as del orden normal y del apllcauvo
! Ls slmllar al orden normal pero evlLa la reevaluacln:
! Los argumenLos son evaluados una sola vez y su valor comun
es comparudo (sharlng)
! LsLa opumlzacln es poslble en lengua[es puros

40
$ twice (10+2)
$ {- definicin -}
$$(10+2) + (10+2)
$ {- aritmtica entera -}
$$12 + 12

twice :: Integer -> Integer
twice x = x + x

valor
compartido
valor
compartido
! Ls una buena prcuca probar los programas
! Las pruebas ayudan a enconLrar errores "
! CulckCheck es una llbrerla de Paskell que ayuda a
probar los programas
! uenlmos propledades que nuesLros programas deben
cumpllr
! CulckCheck genera casos de prueba y verlca las
propledades para esos casos
41
! ropledades en CulckCheck:
0+9&>&,&+9& ==> >%+"&>*&+9&
! 0+9&>&,&+9& y >%+"&>*&+9& deben ser expreslones
booleanas
! uebe leerse como una lmpllcacln lglca: sl el 0+9&>&,&+9&
es clerLo enLonces el >%+"&>*&+9& Lamblen debe serlo
! CulckCheck solo reallza las verlcaclones para propledades
en las que el 0+9&>&,&+9& es clerLo. Las pruebas con
0+9&>&,&+9& falso son descarLadas
! Se debe usar True sl la propledad es el proplo >%+"&>*&+9&
True ==> >%+"&>*&+9&
42
! Algunas propledades:


p1 x y = True ==> square (x+y) == square x + square y + 2*x*y
p2 x y = True ==> abs (x+y) == abs x + abs y
p3 x y = x>=0 && y>=0 ==> abs (x+y) == abs x + abs y

43
square :: (Num a) => a -> a
square x = x * x
Main> quickCheck (p1 :: Integer -> Integer -> Property)
+++ OK, passed 100 tests.
Main> quickCheck (p2 :: Integer -> Integer -> Property)
*** Failed! Falsifiable (after 2 tests):
1
-1
Main> quickCheck (p3 :: Integer -> Integer -> Property)
+++ OK, passed 100 tests.
Fallo en la prueba:
contraejemplo
Hacemos que
QuickCheck pruebe
nuestra propiedad
con enteros
aleatorios
!!"!" " $!$"%&%&!&%$ "&%$%!"
!!"!" " '!$"'&'!'$'"'
!!()"!"() " '!$"'&'!'$'"'
! Son esLrucLuras de daLos heLerogeneas:
! Ls una coleccln ordenada de valores (componenLes)
! Cada componenLe puede Lener un upo dlsunLo
! SlnLaxls:
! Los valores se separan por comas y se colocan enLre
parenLesls
! Los upos de cada componenLe se separan por comas y
se colocan enLre parenLesls
(True, 2) :: (Bool, Int)
(10, 2, 7) :: (Int, Int, Int)
44
succPred :: Int -> (Int, Int)
succPred x = (x+1, x-1)

succPred 10
$ {- definicin -}
(10+1, 10-1)
$ {- aritmtica -}
(11, 9)

43
! lunclones predenldas que exLraen las componenLes de una Lupla:

fst :: (a,b) -> a
fst (x,y) = x





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

Patrn de una 2-
tupla
a y b son variables de tipo; fst toma
una 2-tupla con componentes de tipos
arbitrarios a y b. Se dice que fst es
polimrfica.
P
r
e
l
u
d
e

P
r
e
l
u
d
e

Indica una
funcin
predefinida
Debe leerse como:
a, b . (a,b) -> a
46
fst (1, True)
$ {- definicin -}
1


snd (1, True)
$ {- definicin -}
True
! una ?'#$& <& @*.$ es un con[unLo de upos que comparLen alguna operacln
! Num es la clase predenlda para los upos numerlcos (enLeros, oLanLes,
raclonales, ...)
! Algunos operadores y funclones solamenLe uenen slgnlcado para upos
numerlcos:


(+), (-), (*) :: (Num a) => a -> a -> a


P
r
e
l
u
d
e

tipo sobrecargado
a debe ser una
instancia de Num; es
decir, debe ser
numrico
Los operandos y el resultado
tienen que ser del mismo tipo
debe leerse como:
a Num . a -> a -> a
47
hup://en.wlklpedla.org/wlkl/1ype_class

Prelude> 1 + 2
3
Prelude> 3.5 * 2.5
8.75
Prelude> 3.5 * 2
7.0
Prelude> 'a' + 'b'
<interactive>:1:0:
$$$$No instance for (Num Char)
$$$$$$arising from a use of `+' at <interactive>:1:0-8
$$$$Possible fix: add an instance declaration for (Num Char)
$$$$In the expression: 'a' + 'b'
$$$$In the definition of `it': it = 'a' + 'b'
suma sobre
Integer
producto sobre
Floating
2 est sobrecargado
Char no es de la clase Num
Type error
48
! Integral es la clase que agrupa los upos de numeros enLeros
! 1lene funclones especlcas para operar con enLeros:


div, mod :: (Integral a) => a -> a -> a





P
r
e
l
u
d
e

Tipo sobrecargado:
debe ser de la clase
Integral
debe leerse como:
a Integral . a -> a -> a
cociente y resto de la
divisin entera
Prelude> div 10 3
3
Prelude> mod 10 3
1
Prelude> div 10.5 2.5
<interactive>:1:9:
Ambiguous type variable `t' in the constraints:
`Fractional t'
arising from the literal `2.5' at <interactive>:1:9-11
`Integral t' arising from a use of `div' at <interactive>:1:0-11
Probable fix: add a type signature that fixes these type variable(s)
Los nmeros Floating no
son Integral.
Type error
49
! Fractional es la clase que agrupa los upos de numeros fracclonarlos:
oLanLes y raclonales (coclenLes de enLeros , ...)
! La funcln esenclal es la dlvlsln:


(/) :: (Fractional a) => a -> a -> a





P
r
e
l
u
d
e

El tipo a debe ser
de la clase
Fractional
Esto debe leerse como:
a Fractional . a -> a -> a
Divisin
fraccionaria

Prelude> 26.25 / 7.5
3.5
Prelude> 10 / 3
3.3333333333333335

10 y 3 estn
sobrecargados
30
twice' :: (Num a) => a -> a
twice' x = x + x
Main> twice' 10
20
Main> twice' 3.25
6.5
Main> twice' True
<interactive>:1:0:
No instance for (Num Bool)
arising from a use of `twice'' at <interactive>:1:0-4
Possible fix: add an instance declaration for (Num Bool)
In the expression: twice True
In the definition of `it': it = twice' True
Esta funcin usa el operador
sobrecargado +; solo puede ser
aplicada a tipos numricos; la
funcin hereda el contexto Num a
31
! Ord es la clase de los upos para los cuales exlsLe una relacln de orden LoLal,
enLre esLos aparecen lnLeger, uouble, 8auonal, 8ool, .
! ClerLos operadores (<, max, .) solo uenen senudo para las lnsLanclas de Ord:

(<), (<=), (>), (>=) :: (Ord a) => a -> a -> Bool



compare :: (Ord a) => a -> a -> Ordering
data Ordering = LT | EQ | GT




max, min :: (Ord a) => a -> a -> a
P
r
e
l
u
d
e

a debe ser una
instancia de Ord
Solo podemos comparar valores
del mismo tipo, y el resultado
siempre ser un booleano
Debe leerse como:
a Ord . a -> a -> Bool
P
r
e
l
u
d
e

mximo y mnimo de dos
valores del mismo tipo,
instancia a su vez de Ord
32
P
r
e
l
u
d
e

Tipo enumerado predefinido:
compare 3 4 $ L1
compare 3.0 3.0000000000000001 $ LC
! Eq es la clase de los upos para los cuales exlsLe una relacln de lgualdad, enLre
esLos aparecen lnLeger, uouble, 8auonal, 8ool, .
! La clase lncluye dos operadores:


(==), (/=) :: (Eq a) => a -> a -> Bool






P
r
e
l
u
d
e

a debe ser una
instancia de Eq
Solo podemos comparar
valores del mismo tipo, y
el resultado siempre ser
un booleano
Debe leerse como:
a Eq . a -> a -> Bool
33
34
Prelude> 1 < 2
True
Prelude> 1 == 2
False
Prelude> 1 /= 2
True
Prelude> compare 1 2
LT
Prelude> compare 10 2
GT
Prelude> compare 1 1
EQ
Prelude> 'a' > z'
False
Prelude> max 3.5 7.8
7.8
Prelude> min 3.5 2.0
2.0
1 es menor que 2
1 no es igual a 2
1 es distinto de 2
1 es Less Than 2
10 es Greater Than 2
1 es EQual a 1
El mayor de 3.5 y 7.8 es 7.8
El menor de 3.5 y 2.0 es 2.0

Eq (==), (/=)
Ord
(<), (<=), (>), (>=)
Num (+), (-), (*)
Integral div mod
Fractional (/)
33
! A menudo es ms senclllo descrlblr una
funcln 6%' 60'9&":

sign 5 $ 1 sign (-2) $ -1
sign 0 $ 0

sign :: (Ord a,Num a) => a -> a
sign x | x > 0 $ = 1
| x < 0 $$= -1
| x == 0 $= 0

Su valor es 1, si el
argumento es positivo
Guardas booleanas
Su valor es -1, si el
argumento es negativo
Su valor es 0, si el
argumento es nulo
36
hup://en.wlklpedla.org/wlkl/Cuard_(compuung)
Atencin al
sangrado . Los
separadores
en la misma
columna
! La denlcln anLerlor:
sign :: (Ord a, Num a) => a -> a
sign x | x > 0 $= $ 1
| x < 0 $$= -1
| x == 0 $= 0
! puede escrlblrse de forma ms expreslva (esulo preferenLe):
sign :: (Ord a, Num a) => a -> a
sign x | x > 0 $ = $1
| x < 0 $$ = -1
| otherwise = 0


otherwise: esta condicin
siempre es cierta. Ser
seleccionada si fallan las
previas
37
otherwise :: Bool
otherwise = True
P
r
e
l
u
d
e

! Las expreslones condlclonales proporclonan una
alLernauva a las formas guardadas:
abs :: (Ord a, Num a) => a -> a
abs x = if x >= 0 then x else x
-- versln con guardas
abs :: (Ord a, Num a) => a -> a
abs x | x >= 0 = x
| otherwise = x

P
r
e
l
u
d
e

38
! Pay funclones denldas solo parclalmenLe:
! Main> reciprocal 0
*** Exception: reciprocal undefined
! LsLo se conslgue vla la funcln error:
reciprocal :: (Fractional a) => a -> a
reciprocal x | x == 0 = error$reciprocal undefined"
$$$$$$ | otherwise $= 1 / x

! Lrror es una funcln pollmrca:
error :: String -> a
39
el valor de tipo String
describe la
excepcin
P
r
e
l
u
d
e

! La palabra reservada where permlLe denlr funclones o varlables
locales, y debe aparecer al nal de la denlcln
circArea :: Double -> Double
circArea r = pi*r^2

rectArea :: Double -> Double -> Double


rectArea b h = b*h

circLength :: Double -> Double


circLength r = 2*pi*r

cylinderArea :: Double -> Double -> Double


cylinderArea r h = 2*circ + rect
$ where
circ = circArea r
$$$$$$ l = circLength r
$$$$$$$ rect = rectArea l h
where: debe
sangrarse con
respecto a la funcin
Las definiciones locales deben
sangrarse al mismo nivel
r
h
l
60
! una alLernauva para lnLroduclr denlclones locales es vla la
consLruccln let in
circArea :: Double -> Double
circArea r = pi*r^2

rectArea :: Double -> Double -> Double


rectArea b h = b*h

circLength :: Double -> Double


circLength r = 2*pi*r

cylinderArea :: Double -> Double -> Double


cylinderArea r h =
$ let
circ = circArea r
l = circLength r
$$ rect = rectArea l h
$ in
2*circ + rect
$
resultado de la
expresin let in
Las definiciones locales
deben estar sangrarse
al mismo nivel
r
h
l
61
! Ln un Ll (lengua[e funclonal puro), la denlcln:
g x :: Integer -> Integer
g x = f x + h (10*x) `div` f x

puede reemplazarse por :
g x :: Integer -> Integer
g x = y + h (10*x) `div` y where y = f x
sln modlcar el slgnlcado del programa.
! LsLa sencllla Lransformacln es una opumlzacln:
f x solamenLe se compuLa (evalua) una vez

! Adems, la expresln y + h (10*x) `div` y where y = f x
puede evaluarse vla paralellsmo
! Lo anLerlor no es vlldo en lengua[es lmpuros #

62

S-ar putea să vă placă și