2013-02-18 5 views
6

Предположим, у меня есть две функции: f:X->Y и g:Y*Y->Z. Я хочу сделать третью функцию, h(a, b) = g(f(a), f(b)).цепные многопараметрические функции

h a b = g (f a) (f b) 

Есть ли способ, чтобы написать ее как h(a, b) = g*f (a, b)?

А что, если h(a,b,c,d) = g2*g1*f2*f1 (a,b,c,d), где g_i занимает 2 аргумента?

+0

ваших двух примеров не синхронизировано. Первым должен быть «g (f1 a) (f2 b)» или второй «g (f a) (f b) (f c) (f d)». –

+0

Вы можете написать 'h = \ a b -> g (f a) (f b)' как 'h = (. F). г . f', но вы не должны (читаемость). –

+0

в вашем новом втором примере, вы имеете в виду функции 'f', принимающие' arg, и 'g' funcs, принимающие 2? Тогда вам нужен 3-й уровень. Не могли бы вы написать его полностью? –

ответ

10

Поиск в Hoogle для функций с помощью right signature показывает on из Data.Function. Согласно его документации,

g `on` f 

похоже, что вы хотите.

7

on комбинатор (в Data.Function, как указал gspr в другой ответ) определяется

g `on` f = \x y -> g (f x) (f y) 

Который позволит вам написать

h = g `on` f 

Вы можете сделать многомерные обобщения из этого, например

g `on3` f = \x y z -> g (f x) (f y) (f z) 

g `on4` f = \w x y z -> g (f w) (f x) (f y) (f z) 

Так что вы могли бы написать

h = g `on3` f 

Там может быть способ, чтобы написать on3 и on4 с точки зрения on, но если я не могу видеть его в данный момент.

6

Вы также можете найти стрелки интересные. Вот один из способов сделать это:

h g f a b = uncurry g ((f *** f) (a, b)) 

что эквивалентно вашему примеру (кроме того, что g и f не являются свободными) и on.Использование:

  • definition из *** для функций:

    (***) f g ~(x,y) = (f x, g y) 
    
  • definition из uncurry:

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

И подставляя их в исходное уравнение:

  1. h g f a b = uncurry g (f a, f b)(используется *** определение)

  2. h g f a b = g (f a) (f b)(используются uncurry определение)

Смежные вопросы