2015-12-13 3 views
2

У меня есть несколько мест в моем коде, которые выглядят следующим образом:OCaml карта на кортеж

let (a,b,c) = (f "a", f "b", f "c") 

Было бы хорошо, если я могу написать что-то вроде:

let (a,b,c) = map f ("a", "b", "c") 

Если есть способ сделать что-то подобное в OCaml?

+0

Будут ли ваши 'a',' b' и 'c' всегда иметь один и тот же тип? Является ли ваш 'f' всегда предназначаемым для распределения по упорядоченной тройке того же типа? – Shredderroy

+0

Система типа OCaml не поддерживает массивы определенной длины или однородные кортежи, параметризованные их длиной. Если бы у нас были такие, тогда у вас могла бы быть одна функция отображения типа '('a ->' b) -> ('a, ) array -> (' b, ) array' –

ответ

5

Вы можете легко написать map для троек одного типа элемента:

let map_triple f (a, b, c) = (f a, f b, f c) 

let a, b, c = map_triple String.length ("foo", "bar", "quux") 

Это будет работать только для одной длины кортежа, однако.

Можно было бы написать тип GADTified tuple и написать map над этим типом, который является полиморфным по длине кортежа, но такого рода обман лучше избегать, если преимущество не велико, что не кажется в данном случае.

5

Лучшим ответом является то, что вы не можете этого сделать, если хотите, чтобы он работал на кортежи разных размеров. Каждый размер кортежа отличается от OCaml. Таким образом, не существует типа OCaml, представляющего идею «кортежа любого размера, элементами которого являются строки».

Но на самом деле это звучит как список больше, чем кортеж. Если вы можете использовать списки вместо кортежей, вы можете использовать обычную старую функцию List.map.

+0

Я не против использования списка .map, но я wan, чтобы иметь возможность легко привязывать результаты к переменным: – krokodil

+1

Вы можете легко написать функцию для каждого размера кортежа: 'let mapt3 f (a, b, c) = (fa, fb, fc)'. Если у вас есть только несколько размеров, это может быть достойным решением. –

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