0votos

Min y Max en Haskell

por josejuan hace 3 años

Min y max son dos selecciones basadas directamente en una relación preestablecida (en este caso de orden). En Haskell, la relación de orden es normalmente `Ord`.

Escribir el par de funciones min y max para dos elementos. ¡OJO! Este desafío parece facilísimo, sin embargo, hay un detalle muy sutil que puede ser pasado por alto.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
-- `min` y `max` forman parte de las funciones "selectoras" (`sel`) 
 
-- la función `sel` puede escribirse como 
sel f a b |  a `f` b   = a 
          | otherwise  = b 
 
 
-- las funciones `min` y `max` pueden escribirse como 
min = sel (<) 
max = sel (>) 
 
 
-- la carga del orden recae sobre la clase `Ord` 
 
-- supongamos que la relación de orden entre dos números enteros 
-- es la relación estándar entre los dos números al suprimir en su 
-- representación decimal los dígitos impares (base 1) 
 
data XInt a = XInt a deriving (Eq, Show) 
 
reduceXInt (XInt 0) = 0 
reduceXInt (XInt n) = (10 * reduceXInt (XInt d)) + r `div` 10 
                      where (d, r) = n `divMod` 100 
 
instance (Integral a, Eq a) => Ord (XInt a) where 
  compare = (.reduceXInt).compare.reduceXInt 
 
 
{- entonces tenemos 
 
   *Main> XInt 1030 `compare` XInt 1535 
   EQ 
   *Main> XInt 1040 `compare` XInt 1535 
   GT 
   *Main> min (XInt 1040) (XInt 1535) 
   XInt 1535 
   *Main> max (XInt 1040) (XInt 1535) 
   XInt 1040 
   *Main> 
 
-} 
 
 
-- notar que la clase de equivalencia `Eq` es diferente a la clase 
-- de orden `Ord`, como se ha derivado automáticamente `Eq` se tiene 
{- 
 
   *Main> XInt 1030 `compare` XInt 1535 
   EQ 
   *Main> XInt 1030 == XInt 1535 
   False 
   *Main> 
 
-} 
 
-- lo cual es perfectamente válido y coherente. 
 
-- Si se quiere ocultar la estructura interna de `XInt` y coordinar 
-- (lo que en la práctica parece más razonable) su comportamiento en 
-- las clases `Eq` y `Ord` sólo es instanciar en `Eq` (en lugar de 
-- derivar) 
 
instance Integral a => Eq (XInt a) where 
  a == b = reduceXInt a == reduceXInt b 
 
 
-- Entonces, si se quiere determinar realmente cuando dos `XInt` son 
-- internamente diferentes, debe definirse algo como 
 
internalEq (XInt a) (XInt b) = a == b 
internalCompare (XInt a) (XInt b) = a `compare` b 
1 comentario
0votos

Escrito por Fernando Pelliccioni hace 3 años

Hola JoseJuan,

Muy buena tu solución.
Por limitaciones de la página, puse mis comentarios en ...

http://www.solveet.com/exercises/Min-y-Max/244/solution-1694

Saludos,
Fernando.

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.