La tua firma del tipo non funzionerà. Devi essere in grado di fornire alla funzione passata un elenco di tuple, il che significa che devi utilizzare tipi di rango più elevato per forzare la polimorfizzazione, o menzionare esplicitamente le tuple nella tua firma del tipo.
Senza questo, non è possibile "guardare dentro" la funzione per vedere come riordina gli elementi della lista. Infatti, data la tua firma del tipo, la funzione passata poteva fare tutto ciò che voleva nella lista, incluso inserire elementi che non erano nemmeno lì per cominciare!
Ecco quello che ho avuto modo di lavorare con i tipi più alto rango:
{-# LANGUAGE RankNTypes #-}
import Data.List (sortBy)
import Data.Ord (comparing)
indexesOf :: (forall b. (b -> a) -> [b] -> [b]) -> [a] -> [Int]
indexesOf f xs = map snd $ f fst $ zip xs [0..]
foo :: (Ord a, Num a) => [a] -> [Int]
foo = indexesOf (filter . ((< 10) .))
bar :: Ord a => [a] -> [Int]
bar = indexesOf (sortBy . comparing)
Nota che ho dovuto anche aggiungere un argomento in più per la funzione passata per dirgli come estrarre la parte che preoccupa dal elementi della lista su cui sta lavorando. Senza questo, si sarà in grado di utilizzare solo le funzioni che non controllano gli elementi dell'elenco, come ad esempio reverse
e che non sarebbe molto utile.
Esempio eseguito in GHCi:
> let xs = [42, 0, 7, 3, 12, 17, 99, 36, 8]
> foo xs
[1,2,3,8]
> bar xs
[1,3,2,8,4,5,7,0,6]
> indexesOf (const reverse) xs
[8,7,6,5,4,3,2,1,0]
... sono davvero non è chiaro quello che si stai cercando di fare. –
Ho una funzione che lavora su una lista, dico 'sort'. Ora invece della lista ordinata voglio recuperare gli * indici * degli elementi. Per esempio. per '[5.0, 8.0, 7.0]' Non voglio '[5.0. 7.0, 8.0] 'ma' [0,2,1] '. – Landei