0votos

Compra de articulo en Haskell

por josejuan hace 5 años

Solución orientada al typesafe y unit measurement. Nunca aplicaría semejante política de precios :P

El ejercicio es en .net, lo estoy desarollando en la plataforma de webmatrix 3 y como apenas estoy aprendiendo no he dado con su respuesta.

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
{-# LANGUAGE MultiParamTypeClasses, GeneralizedNewtypeDeriving #-} 
 
-- La gestión y operación de importes y descuentos es `typesafe` 
-- por ejemplo no se pueden multiplicar dos importes (de moneda) 
-- pero sí pueden sumarse o restarse, en cambio, una moneda y 
-- un descuento pueden multiplicarse pero no pueden sumarse ni 
-- restarse. 
 
newtype Currency = Currency Double deriving (Show, Eq, Ord, Num) 
newtype Discount = Discount Double deriving (Show, Eq, Ord, Num) 
 
class Ring a b where 
    (*.) :: a -> b -> a; (*.) _ _ = error "¡No implementado!" 
    (+.) :: a -> b -> a; (+.) _ _ = error "¡No implementado!" 
    (-.) :: a -> b -> a; (-.) _ _ = error "¡No implementado!" 
 
instance Ring Currency Currency where 
    (Currency a) +. (Currency b) = Currency (a + b) 
    (Currency a) -. (Currency b) = Currency (a - b) 
 
instance Ring Currency Discount where 
    (Currency a) *. (Discount b) = Currency (a * (1 - b * 0.01)) 
 
 
 
 
-- Para seguir con typesafe, lo suyo es no usar argumentos cuyos tipos 
-- sean compartidos (ej. el importe a evaluar y el importe de filtro), por eso, 
-- creamos un tipo `Rule` 
 
data Rule = Rule { ruleAmount   :: Currency 
                 , ruleDiscount :: Discount 
                 } deriving (Show) 
 
 
-- Ahora podemos implementar nuestra regla de negocio de forma segura (typesafe) 
computePrice rule amount = amount *. discount 
 
    where discount = if amount > ruleAmount rule 
                        then ruleDiscount rule 
                        else Discount 0 
 
 
 
-- Por ejemplo 
test0 = computePrice (Rule (Currency 100) (Discount 20)) (Currency 100) 
 
-- O bien, si se quiere realizar una `autoconversión` entre números y nuestros tipos 
-- añadiendo `GeneralizedNewtypeDeriving`, ventaja, es más cómodo, desventaja, esas 
-- constantes no son typesafe "perse" 
test1 = computePrice (Rule 100 20) 100 

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.