2012-03-11 27 views
13

Estoy tratando de escribir una función de composición de función variable. Que es básicamente el (.), excepto que la segunda función de argumento es variadica. Esto debería permitir expresiones como:Función de composición variable

map even . zipWith (+) 

o simplemente

map even . zipWith 

Actualmente lo que he alcanzado obras si añado IncoherentInstances y requiere una instancia no polimórficos para la primera función argumento.

{-# LANGUAGE FlexibleInstances, OverlappingInstances, MultiParamTypeClasses, 
FunctionalDependencies, UndecidableInstances, KindSignatures #-} 

class Comp a b c d | c -> d where 
    comp :: (a -> b) -> c -> d 

instance Comp a b (a :: *) (b :: *) where 
    comp f g = f g 

instance Comp c d b e => Comp c d (a -> b) (a -> e) where 
    comp f g = comp f . g 

¿Alguna idea? ¿Es posible?

+1

se puede explicar un poco más lo que quiere usted decir con "la composición de funciones variadic "¿?" tal vez agregue algunos ejemplos. –

+0

Aclaré un poco en la última edición. Además de eso, ¿qué pasa con los dos ejemplos dados? – is7s

+0

Oh, lo siento. Los ejemplos están bien. No fue obvio para mí que no mecanografíen. –

Respuesta

9

Es posible escribir-Hack en el trabajo con funciones polimórficas:

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, 
    IncoherentInstances, UndecidableInstances, 
    FunctionalDependencies, TypeFamilies, 
    NoMonomorphismRestriction #-} 


class Comp a b c | a b -> c where 
    (...) :: a -> b -> c 

instance (a ~ c, r ~ b) => Comp (a -> b) c r where 
    f ... g = f g 

instance (Comp (a -> b) d r1, r ~ (c -> r1)) => Comp (a -> b) (c -> d) r where 
    f ... g = \c -> f ... g c 

t1 = map even ... zipWith (+) 
t2 = map even ... zipWith 
t3 = (+1) ... foldr 

pero dudo que pueda evitar IncoherentInstances