tutorial shampoo online empresa descargar constructora company haskell

online - haskell shampoo



¿Cómo escribiría esta función en un estilo sin puntos? (2)

Solo estoy buscando hacer mejoras generales en mi código Haskell, y me preguntaba si la siguiente función podría quedar libre de puntos. Sobre todo por el bien de la curiosidad.

Dadas dos funciones que nos gustaría usar en nuestro filter :

isZero = (==0) isOne = (==1)

¿Cómo podríamos utilizar esas dos funciones en nuestro ejemplo artificial, pero hacerlo sin puntos?

filter (/x -> isZero x || isOne x) [0..100]


Hay un online-service para convertir Haskell código de Haskell en un punto libre.

Se sugiere: filter (liftM2 (||) isZero isOne) [0..100]

liftA2 (||) isZero isOne o (||) <$> isZero <*> isOne también es posible

(||) <$> isZero tiene el tipo a0 -> Bool -> Bool y es la composición de (||) e isZero . Esta composición toma un número (para isZero ) y un booleano (como otro argumento para (||) )

Entonces, es lo mismo que /xy -> (||) (isZero x) y

El tipo de función es una instancia de Applicative Functor y podemos ver su implementación:

instance Applicative ((->) r) where pure x = (/_ -> x) f <*> g = /x -> f x (g x)

Entonces, (||) <$> isZero <*> isOne es lo mismo que /x -> ((||) <$> isZero) x (isOne x) y lo mismo que /x -> (||) (isZero x) (isOne x)

Por lo tanto, si hay zx = y (fx) (gx) , se puede transformar en punto libre: z = y <$> f <*> g


Una forma libre de puntos alternativa sería utilizar a -> Any mono a -> Any monoide:

λ import Data.Monoid (Any(..)) λ :t getAny . (Any . isZero <> Any . isOne) getAny . (Any . isZero <> Any . isOne) :: (Num a, Eq a) => a -> Bool λ filter (getAny . (Any . isZero <> Any . isOne)) [0..100] [0,1]

Es un poco más largo que la solución Applicative , pero creo que es un poco más fácil de seguir cuando tienes más condiciones para combinar. Comparar

getAny . (Any . isZero <> Any . isOne <> Any . isSquare <> Any . isPrime)

o

getAny . foldMap (Any .) [isZero, isOne, isSquare, isPrime]

y

liftA2 (||) (liftA2 (||) (liftA2 (||) isZero isOne) isSquare) isPrime

o

liftA2 (||) isZero $ liftA2 (||) isOne $ liftA2 (||) isSquare isPrime

Aunque para ser honesto, si tuviera que hacer muchas de estas cosas, me sentiría tentado a definir <||> = liftA2 (||) y hacer

isZero <||> isOne <||> isSquare <||> isPrime