2012-03-11 10 views
13

Próbuję napisać funkcję składu funkcji variadic. Który jest w zasadzie (.), z tym że druga funkcja argumentu jest wariantowa. Powinno to umożliwić wyrażenia jak:Funkcja komponowania Variadic?

map even . zipWith (+) 

lub po prostu

map even . zipWith 

Obecnie co już osiągnęły prace jeśli dodam IncoherentInstances i wymaga non-polimorficzny instancję dla funkcji pierwszy argument.

{-# 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 

Wszelkie pomysły? Czy to możliwe?

+1

można wyjaśnić nieco więcej, co masz na myśli przez „o zmiennej liczbie argumentów złożenie funkcji "? może dodać kilka przykładów. –

+0

Wyjaśniłem trochę w ostatniej edycji. Poza tym, co jest nie tak z tymi dwoma podanymi przykładami? – is7s

+0

Och, przepraszam. Przykłady są w porządku. Nie było dla mnie oczywiste, że nie sprawdzają poprawności. –

Odpowiedz

9

Jest możliwe, aby wpisać-Hack go do pracy z polimorficznych funkcji:

{-# 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 

ale wątpię można uniknąć IncoherentInstances

Powiązane problemy