2012-01-26 8 views

Respuesta

18

Esta es la instancia Applicative para ((->) r), funciones de un tipo común. Combina funciones con el mismo tipo de primer argumento en una sola función al duplicar un solo argumento para usar en todos ellos. (<$>) es la composición de funciones, es pura const, y esto es lo que se traduce en (<*>):

s :: (r -> a -> b) -> (r -> a) -> r -> b 
s f g x = f x (g x) 

Esta función es quizás mejor conocido como the S combinator.

El funtor ((->) r) es también el Reader mónada, donde el argumento común es el valor "medio ambiente", por ejemplo:

newtype Reader r a = Reader (r -> a) 

yo no diría que es común hacer esto por el bien de hacer funciona sin puntos, pero en algunos casos puede mejorar la claridad una vez que estás acostumbrado a la expresión idiomática. El ejemplo que usted dio, por ejemplo, puedo leer muy fácilmente como "es un personaje una letra o número".

+0

s f g x = s x (g x) debe ser s f g x = f x (g x) – hvintus

+0

@hvintus: Whoops, typo. ¡Gracias! –

7

Obtiene instancias de las llamadas flechas estáticas (consulte "Programación aplicable con efectos" por Conor McBride y otros) gratis desde el paquete Control.Applicative. Por lo tanto, cualquier tipo de fuente, en su caso Char, da lugar a una instancia Aplicable donde cualquier otro tipo a se mapea al tipo Char -> a.

Al combinar cualquiera de estos, dicen aplica una función f :: Char -> a -> b a un valor x :: Char -> a, la semántica es que se crea una nueva función Char -> b, que alimentarán su argumento en tanto f y x como tal,

f <*> x = \c -> (f c) (x c) 

Por lo tanto, como usted señala, esto hace que su ejemplo equivalente a

isAlphaNum c = (isAlpha c) || (isNum c) 

En mi opinión, estos esfuerzos no siempre es necesaria, y que se vería más bonito si Haskell tuviera un mejor soporte sintáctico para los aplicativos (tal vez algo así como los idiomas de 2 niveles).

3

Debe tenerse en cuenta que obtiene un efecto similar al utilizar las funciones de elevación, p.:

import Data.Char 
import Control.Applicative 

isAlphaNum = liftA2 (||) isAlpha isNumber 

O, utilizando la instancia mónada de ((->) r) en lugar del aplicativo uno:

import Data.Char 
import Control.Monad 

isAlphaNum = liftM2 (||) isAlpha isNumber 

[Digresión]

Ahora que ya sabe cómo distribuir un argumentodos funciones intermedias y el resultado de una función binaria, existe el caso relacionado de alguna manera que desea distrib UTE dos argumentos a uno función intermedia y los resultados a una función binaria:

import Data.Function 

orFst = (||) `on` fst 

-- orFst (True,3) (False, 7) 
--> True 

Este patrón es, por ejemplo, de uso frecuente para la función compare.

+2

También hay 'Control.Concatenative' que trae algunos combinadores concatenativos estándar en Haskell. Sus ejemplos podrían ser 'bi isAlpha isNumber (||)' y 'fst \' biAp \ '(||)'. No necesariamente se muestra aquí, pero 'Control.Concatenative' ayuda a mejorar la legibilidad de muchas expresiones sin puntos, porque, bueno, de eso se trata la programación concatenativa. –

+0

Gracias, tengo que revisar este módulo ... – Landei

Cuestiones relacionadas