He estado tratando de "aprenderme un Haskell" a través del libro en línea LYAH.una generalización simple de la clase de tipo Applicative (Functor); coincidencia de patrones en constructores
El autor describe el comportamiento de los Funcionadores del tipo Aplicativo como si tuvieran la capacidad de extraer una función de un funtor y asignarla a un segundo funtor; esto es a través del *> función < declarado para la clase de tipo aplicativo:
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Como un simple ejemplo, el tipo Tal vez es una instancia de Aplicativo bajo la siguiente aplicación:
instance Applicative Maybe where
pure = Just
Nothing <*> _ = Nothing
(Just f) <*> something = fmap f something
Un ejemplo de el comportamiento mencionado anteriormente:
ghci> Just (*2) <*> Just 10 -- evaluates to Just 20
por lo que el *> operador < "extrae" el (* 2) función del primer operando y el mapa s en el segundo operando.
Ahora, en los tipos Applicative, ambos operandos de < *> son del mismo tipo, así que pensé como ejercicio, ¿por qué no intentar implementar una generalización de este comportamiento, donde los dos operandos son Functors de diferentes tipos, por lo que pude evaluar algo como esto:
Just (2*) <*:*> [1,2,3,4] -- should evaluate to [2,4,6,8]
Así que esto es lo que ocurrió:
import Control.Applicative
class (Applicative f, Functor g) => DApplicative f g where
pure1 :: a -> f a
pure1 = pure
(<*:*>) :: f (a -> b) -> g a -> g b -- referred below as (1)
instance DApplicative Maybe [] where -- an "instance pair" of this class
(Just func) <*:*> g = fmap func g
main = do putStrLn(show x)
where x = Just (2*) <*:*> [1,2,3,4] -- it works, x equals [2,4,6,8]
Ahora, a pesar de lo anterior funciona, me pregunto si podemos hacerlo mejor; ¿Es posible dar una implementación predeterminada para < *: *> que se puede aplicar a una variedad de pares f & g, en la declaración para DApplicative f g en sí? Y esto me lleva a la siguiente pregunta: ¿Hay alguna forma de emparejar patrones en constructores en diferentes tipos de datos?
espero que mis preguntas hacen algún sentido y no estoy simplemente arrojando sin sentido (si lo estoy, por favor, no ser demasiado duro, sólo soy un principiante hasta FP camino más allá de su hora de dormir ...)
gracias por la respuesta completa ... Todavía no he revisado tu código a fondo, pero entiendo la idea general. – Aky