¡Es hora de anunciar Haskell!
Este problema no es el mejor para presumir la elegancia de Haskell (o para decir que todavía soy bastante nuevo en Haskell), pero sigue siendo una frase:
let masb = if b `rem` a == 0 then Just s else Nada en [maybe (show x) id $ m 3″ abc “x m 5” def “x | x <- [100..200]]
- Cómo verificar si un cuadrado dibujado está cerrado (tiene los 4 lados dibujados)
- ¿Cómo podemos dividir un conjunto dado de números (posiblemente negativos) en dos partes que tienen el mismo promedio?
- Algoritmos: ¿Qué sucede cuando un usuario crea una matriz de tamaño -100, qué sucede en la memoria?
- ¿Cuál es la licencia del algoritmo de agrupación combinatoria multiescala?
- Cómo implementar un algoritmo de programación de CPU del sistema operativo que evita que se produzcan puntos muertos
(En realidad, también necesitará importar Data.Monoid )
Eso produce
OK, separemos el código:
[quizás (muestre x) id $ m 3 “abc” x m 5 “def” x | x <- [100..200]]
dónde
masb = if b `rem` a == 0 entonces s s else nada
Son equivalentes, pero usando “donde” puede ver que definí una función m.
Pienso en la lógica como dos pasos:
- Si ‘x’ es múltiplo de 3, entonces devuelva “abc” else “” (cadena vacía), si es múltiplo de 5, entonces “def” else “”, y concatenelos juntos.
- Si la cadena de un número sale vacía, entonces dote la forma de cadena del número en sí, es decir, muestra x .
Para el paso 1, bien podría haber usado
m ‘asb = si b `rem` a == 0 entonces s else” ”
pero luego, para el paso 2, tengo que decidir si el resultado del paso 1 está vacío, lo que me obliga a definir otra función (¡y menos elegante!)
Por lo tanto, utilicé el tipo incorporado Quizás :
datos Tal vez a = Solo a | Nada
Por ejemplo, Quizás String contiene un String dentro del constructor Just , o no contiene un String (y obtenemos Nothing ).
La cuestión es,
instancia (Monoide a) => Monoide (Quizás a)
Si un tipo es un monoide, entonces tiene un valor cero ( mempty ) y una operación para “agregar” dos valores juntos ( mappend ), por ejemplo los números: (0, +).
Para cadenas, aparentemente la estructura es (“”, ++).
Esto dice que si un es un monoide, luego envolver un interior tal vez automáticamente hace un monoide . ¿Cómo?
mempty = nada
mappend (Just x) (Just y) = Just (x `mappend` y)
mappend (Just x) (Nothing) = Just x
mappend (Nada) (Solo y) = Solo y
mappend (Nada) (Nada) = Nada
… y casi me olvido de mencionar que
= mappend
Ok, entonces el paso 1 ha finalizado, y en caso de “”, se devuelve Nothing .
La función quizás está incorporada para tratar con Quizás :
quizás :: a -> (b -> a) -> Quizás b
tal vez éxito fallido F (Solo x) = éxito F x
tal vez éxito fallido F (Nada) = fallido
Por lo tanto, podemos expresar naturalmente el paso 2: si Nothing , la cadena predeterminada es show x; de lo contrario, use la cadena dentro de Just .
En el caso de que successF sea id (la función de identidad), hay una función que guarda este id :
fromMaybe :: a -> Quizás a -> a
fromMaybe defVal (Just x) = x
fromMaybe defVal (Nothing) = defVal
pero luego tienes que importar datos .
Es natural dudar por qué usé tantos “trucos” aquí, pero en realidad son herramientas poderosas en la caja de herramientas de cualquier programador Haskell.
Y ni siquiera estoy hablando de Monad (“solo un monoide en la categoría de endofunctores, ¿cuál es el problema?”)!
Esta es la única cosa que hace que Haskell se parezca al lenguaje del doctorado en matemáticas; OK, Haskell está diseñado sobre la teoría matemática difícil, y un poco de sentido matemático ayuda a aprenderlo, pero realmente no necesitas obtener la teoría de categorías para usar Haskell (tengo un libro de texto de teoría de categorías, en caso de que no pueda dormir) , así como no necesita comprender la estructura de un automóvil para conducirlo.