2013-03-04 13 views
5

Czy istnieje funkcja lub funkcje w Haskell, które pobierają n argumenty i zwraca n-krotkę? Na przykład:Haskell: funkcja "makeNtuple"?

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

tj .: jak przecinek, ale z więcej niż dwóch argumentów. Oczywiście make3tuple wykonuje tę pracę, ale wydaje mi się, że musi istnieć wbudowany sposób, aby to zrobić, i nie znalazłem jej, lub brakowało jakiegoś sposobu użycia innej wszechobecnej funkcji.

FWIW, powstaje, gdy używany jest liftM3 (lub wyższy). Na przykład:

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

Dzięki!

Odpowiedz

12

Tak.

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

itp

Więc można napisać liftM3 (,,) getRandom getRandom getRandom

Haskell kompilatory zapewniają funkcje takie jak to do pewnej wielkości (myślę, że gwarancja jest 15-krotki)

+4

Dzięki rozszerzeniu o nazwie 'TupleSections', można zastosować to nawet częściowo. Zatem '(, 1,, 2)' jest równe '\ x y -> (x, 1, y, 2)'. –

+0

@amindfv Hahahahaha ... najwyraźniej nie przyszło mi do głowy, że przecinek może być użyty w ten sposób. Dzięki! – gwideman

+1

@gwideman: Zauważ, że są to ich własne operatory: '(,,)' jest całkowicie inne niż '(,) (,)'. Gdybyś próbował je skomponować, otrzymalibyśmy coś takiego: '(,) ((,) 3 4) 5', które jest' ((3,4), 5) ' – amindfv

1

nie jako funkcja taka jak makeNtuple :: Int -> a -> a -> ... -> (a,a,...) i pamiętaj, że wydaje się nawet nierozkładalna w języku typu. Jeśli jesteś w porządku z krotki o rodzaj jednorodnej następnie można użyć "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

Wystarczająco uczciwe ... w rzeczywistości nie spodziewałem się generalnego makeNtuple z listą argumentów o zmiennej długości. Można to zrobić z listami i zipem. – gwideman

+1

BTW jest dobrze rozwinięta biblioteka na hackage: [fixed-vector] (http://hackage.haskell.org/package/fixed-vector) – leventov