2015-03-30 3 views
2

Я пытаюсь применить кортеж функций к кортеж значенийПрименяя кортеж функций к кортежу

λ> let foo = ((+1), (*3), ((:)5)) #Each function has type: a -> a 

λ> let bar = (1, 5, [0])   #Each value of the corresponding tuple has type a 

Как реализовать:

toImplement foo bar = ? 

, что:

λ> toImplement foo bar 
-> (2, 15, [0,5]) # using foo and bar above 

Как вы можете реализовать это вообще для любых допустимых foo и bar (одной длины)?

[Я смотрел this problem, но он выполнен для фиксированного типа. Я требую общей реализации]

Мотивации:

Я пытаюсь эффективно писать складки.

let acc1 = \x acc -> x*x:acc 
let acc2 = (+) 
foldr (\x acc -> (acc1 x (fst acc), acc2 x (snd acc))) ([],0) [1..10] 
> ([1,4,9,16,25,36,49,64,81,100],55) 

У меня есть 2 разных аккумуляторов ACC1 & ACC2 этого цикла по списку ровно один раз. Я хотел бы сделать это для произвольного количества аккумуляторов, все из которых имеют тип a -> b [где a - тип элементов в списке, а b - тип выходного сигнала аккумулятора) Он выглядит неуклюжим , имея доступ к кортежам с использованием fst и snd:/

+3

«Как можно реализовать это вообще для любого действительного обув и бар (той же длины)?» --- вы не можете сделать его общим для кортежей. – zerkms

+2

Вы не можете написать ни одно 'toImplement', которое будет работать с кортежами произвольного размера. Конечно, есть некоторые действительно хакерские способы заставить его работать с использованием расширенных языковых функций и кучей расширений, но это, вероятно, больше проблем, чем стоит несколько раз копировать/вставлять одно и то же определение, чтобы получить 'toImplement',' toImplement3 '..' toImplementN'. – bheklilr

+0

Есть ли какой-нибудь zen, почему Haskell не позволяет работать с произвольными кортежами? – GeneralBecos

ответ

6

Как упоминалось в комментариях, haskell не позволяет реализовать общие функции для кортежей произвольного размера. Следовательно, вам нужно реализовать определенную функцию для каждого размера отдельно.

Например:

toImplement3 :: (b0 -> c0, b1 -> c1, b2 -> c2) -> (b0, b1, b2) -> (c0, c1, c2) 
toImplement3 (f1, f2, f3) (a1, a2, a3) = (f1 a1, f2 a2, f3 a3) 
+0

@bheklilr yep спасибо. Немного исправлено это – zerkms

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