2013-03-04 13 views
5

Esiste una funzione o funzioni in Haskell che accetta n argomenti e restituisce una n-tupla? Ad esempio:Haskell: funzione 'makeNtuple'?

make3tuple:: a -> a -> a -> (a,a,a) 
make3tuple a b c = (a,b,c) 

es .: come la virgola, ma per più di due argomenti. Ovviamente make3tuple fa il lavoro, ma ho l'impressione che ci debba essere un modo integrato per farlo, e non l'ho trovato, o mi sono perso un modo per usare qualche altra funzione onnipresente.

FWIW, questo si verifica quando si utilizza liftM3 (o superiore). Ad esempio:

type RandomState a = State StdGen a 
[...] 
getTwoRandoms = liftM2 (,) getRandom getRandom 
get3Randoms = liftM3 make3tuple getRandom getRandom getRandom 

Grazie!

risposta

12

Sì.

(,,) :: a -> b -> c -> (a, b, c) 
(,,,) :: a -> b -> c -> d -> (a, b, c, d) 

ecc

Così si potrebbe scrivere liftM3 (,,) getRandom getRandom getRandom

Haskell compilatori offrono funzioni come questo fino ad una certa dimensione (credo che la garanzia è di 15-tuple)

+4

Con un'estensione chiamata 'TupleSections', si può anche applicare questa parte. Quindi '(, 1,, 2)' è uguale a '\ x y -> (x, 1, y, 2)'. –

+0

@amindfv Hahahahaha ... ovviamente non mi era venuto in mente che la virgola potesse essere usata in quel modo. Grazie! – gwideman

+1

@gwideman: Si noti che questi sono i loro operatori: '(,,)' è totalmente diverso da '(,) (,)'. Se dovessi provare a comporli, otterresti qualcosa come: '(,) ((,) 3 4) 5', che è' ((3,4), 5) ' – amindfv

1

Non come funziona come makeNtuple :: Int -> a -> a -> ... -> (a,a,...) e nota che sembra addirittura non essere esprimibile nella lingua del testo. Se stai bene con la tupla avere un tipo omogeneo quindi è possibile utilizzare "dependently-typed" Vectors

data Nat = Ze | Su Nat 

data Vec :: * -> Nat -> * where 
    Nil :: Vec a Ze 
    Cons :: a -> Vec a n -> Vec a (Su n) 
+0

Abbastanza soddisfacente ... anzi non mi aspettavo un makeNtuple generale con la lista arg di lunghezza variabile. Questo può essere fatto con liste e zip. – gwideman

+1

BTW c'è una libreria ben sviluppata su hackage per questo: [fixed-vector] (http://hackage.haskell.org/package/fixed-vector) – leventov