una qué puras pura matematicas impuras función funciones funcion haskell monads function-composition

haskell - qué - funciones puras js



¿Cómo organizo idiomáticamente mis funciones puras con mis acciones monádicas? (3)

Decidí que hoy es el día en que arregle algunas de mis funciones puras que se ejecutan innecesariamente en una acción monádica. Esto es lo que tengo.

flagWorkDays :: [C.Day] -> Handler [WorkDay] flagWorkDays dayList = flagWeekEnds dayList >>= flagHolidays >>= flagScheduled >>= flagASAP >>= toWorkDays

Aquí está flagWeekEnds, a partir de ahora.

flagWeekEnds :: [C.Day] -> Handler [(C.Day,Availability)] flagWeekEnds dayList = do let yepNope = Prelude.map isWorkDay dayList availability = Prelude.map flagAvailability yepNope return $ Prelude.zip dayList availability

flagHolidays sigue un patrón similar. toWorkDays simplemente cambia un tipo a otro, y es una función pura.

flagScheduled , y flagASAP son acciones monádicas. No estoy seguro de cómo combinar las acciones monádicas con las funciones puras de forma idiomática en flagWorkDays . ¿Podría alguien ayudarme a arreglar los flagWorkDays , asumiendo que los flagWeekEnds flagHolidays flagWeekEnds y los de vacaciones de flagHolidays se han purificado?


No es muy dificil Básicamente, solo reemplaza (>>=) por (.) Y cambia el orden de los operandos. do sintaxis puede ayudar a aclarar. También hice el ejemplo sin punto usando el combinador Kleisli (fish) (<=<) :: (b -> mc) -> (a -> mb) -> a -> mc , que es esencialmente (.) Para mónadas.

import Control.Monad flagWorkDays :: [C.Day] -> Handler [WorkDay] flagWorkDays = fmap toWorkDays . flagASAP <=< flagScheduled . flagHolidays . flagWeekEnds


Para completar la respuesta de FUZxxl, purifiquemos flagWeekEnds :

flagWeekEnds :: [C.Day] -> [(C.Day,Availability)] flagWeekEnds days = days `zip` map (flagAvailability . isWorkDay) days

A menudo se coloca una "s" después de los nombres de las variables ( day -> days ) cuando es una lista (como lo hace con el plural en inglés).


Vamos a dar un paso atrás por un momento. Tiene dos tipos de funciones, algunas puras con tipos de la forma a -> b , y algunas monádicas de tipo a -> mb .

Para evitar confusiones, sigamos con la composición de derecha a izquierda. Si prefiere leer de izquierda a derecha, simplemente invierta el orden de las funciones y reemplace (<=<) con (>=>) , y (.) Con (>>>) de Control.Arrow .

Hay entonces cuatro posibilidades de cómo se pueden componer.

  1. Puro entonces puro. Usar la función de composición regular (.) .

    g :: a -> b f :: b -> c f . g :: a -> c

  2. Pura entonces monádica . También use (.) .

    g :: a -> b f :: b -> m c f . g :: a -> m c

  3. Monádico entonces monádico . Utilice la composición kleisli (<=<) .

    g :: a -> m b f :: b -> m c f <=< g :: a -> m c

  4. Monádico entonces puro . Usa fmap en la función pura y (.) Para componer.

    g :: a -> m b f :: b -> c fmap f . g :: a -> m c

Ignorando los aspectos específicos de los tipos involucrados, sus funciones son:

flagWeekEnds :: a -> b flagHolidays :: b -> c flagScheduled :: c -> m d flagASAP :: d -> m e toWorkDays :: e -> f

Vayamos desde la cima. flagWeekEnds y flagHolidays son puros. Caso 1.

flagHolidays . flagWeekEnds :: a -> c

Esto es puro El siguiente es flagScheduled , que es monádico. Caso 2.

flagScheduled . flagHolidays . flagWeekEnds :: a -> m d

El siguiente es flagASAP , ahora tenemos dos funciones monádicas. Caso 3.

flagASAP <=< flagScheduled . flagHolidays . flagWeekEnds :: a -> m e

Y finalmente, tenemos la función pura de trabajar en toWorkDays . Caso 4.

fmap toWorkDays . flagASAP <=< flagScheduled . flagHolidays . flagWeekEnds :: a -> m f

Y hemos terminado.