2011-05-06 24 views

Respuesta

5

En general, diría que no, no es posible. Sin embargo, si está tratando de resolver el problema práctico de desenvolver y envolver por todos lados (especialmente común con los tipos nuevos), a menudo defino una función mapf f (Type val) = Type (f val), análoga a fmap, y luego no la exporto. Puede hacer lo mismo para un tipo de datos n-aria simplemente pasando más funciones. Si la implementación no se supone que sea secreta, puede exportarla también (como fmap para unary). Recomiendo este tipo de función de mapa o vistas para tipos complicados porque la coincidencia de patrones lo vinculará a la implementación.

Los tipos básicos ya tienen dichas funciones definidas, p. maybe y either.

+0

¿Por qué dice que no es posible en general? Siempre puede definir constructores y funciones deconstructor para reemplazar la coincidencia explícita de patrones; y siempre puede traducir una función de Haskell puntiaguda a una versión pointfree (arbitrariamente complicada). Entonces, en general, * es * posible. –

+0

Sólo una cuestión de terminología, pensé que estaba buscando una solución que no requiriera una función de ayuda. Es decir. sin puntos * coincidencia de patrones *. Si define una función, entonces es funciones sin puntos. Destruir un constructor siempre se reduce a un caso con el tiempo, ¿verdad? Supongo que se podría decir prácticamente que las cosas de programación genérica significan que no tienes que escribir un caso, sino solo porque el compilador lo puso en la instancia de datos automática. –

+1

'maybe' y' either' son en realidad un pliegue sobre el tipo (incluso si el tipo de datos no es recursivo, probablemente sea por eso que no se denominan pliegues), porque convierte un objeto de ese tipo en su codificación Church: usted lo suministra una función correspondiente a cada constructor.Para generar el valor de retorno, las llamadas a esas funciones reemplazan las llamadas a los constructores del tipo de datos. Su 'mapf' es muy similar a' fmap', pero solo para un tipo con 1 constructor que tiene 1 parámetro; de lo contrario, la analogía de los pliegues es más útil. – Blaisorblade

12

Via analogía con tuplas,

data TwoInts = TwoInts { fst', snd' :: Int } 

podemos definir una operación de elevación de funciones de dos argumentos en un TwoInt

uncurry' f p = f (fst' p) (snd' p) 

que nos da la notación agradable:

add'em = uncurry' (+) 
+0

De acuerdo, ahora acabamos de mover los puntos a 'currir'' – alternative

+0

Incluso podría hacer una clase de tipo para cosas curryables, por lo que podría aplicarse a algo más que a TwoInts ... – pat

+8

@mathepic, undecurry se puede escribir pointfree. 'uncurry = ('ap' snd). (. fst) '. La clave es deshacerse de la coincidencia de patrones. –

Cuestiones relacionadas