2010-09-29 12 views
5

Od dawna chciałem nauczyć się Haskella i wiem, że podobne języki mają naprawdę dobre wsparcie dla różnego rodzaju nieskończonych list. Więc jak mógłbym reprezentować sekwencję czworościennych liczb w Haskell, najlepiej z wyjaśnieniem, co się dzieje?Reprezentuję sekwencję czworościennych liczb w Haskellu

0 0 0 
1 1 1 
2 3 4 
3 6 10 
4 10 20 
5 15 35 
6 21 56 
7 28 84 
8 36 120 

W przypadku, gdy nie jest jasne, co się tam dzieje, druga kolumna jest uruchomiony suma pierwszej kolumnie, a trzecia kolumna jest uruchomiony sumie drugiej kolumnie. Wolałbym, aby kod Haskella zachował coś z podejścia "działającego totalnie", ponieważ to koncepcja, którą zastanawiałem się, jak wyrazić.

+0

Dalsze informacje na temat dlaczego poprosiłem: Mam zestaw Buckyballs (http://www.getbuckyballs.com/) i odkryłem, że naprawdę lubią tworzyć pięciokątne bipyramidy (http://en.wikipedia.org/wiki/Pentagonal_bipyramid) z twarzami równobocznymi. Tak więc na podstawie odpowiedzi perimosocordiae, liczby "pięciobocznej bipyramidalnej" to 'scanl1 (+) (scanl1 (+) (1: map (* 5) [1 ..]))'. – jnylen

Odpowiedz

10

Jesteś poprawne, Haskell jest naprawdę miły dla robienia rzeczy tak:

first_col = [0..] 
second_col = scanl1 (+) first_col 
third_col = scanl1 (+) second_col 
  • first_col jest nieskończona lista liczb całkowitych, zaczynając od 0
  • scanl (+) oblicza leniwy suma trwania: Prelude docs

Możemy sprawdzić, czy powyższy kod jest właściwy:

Prelude> take 10 first_col 
[0,1,2,3,4,5,6,7,8,9] 
Prelude> take 10 second_col 
[0,1,3,6,10,15,21,28,36,45] 
Prelude> take 10 third_col 
[0,1,4,10,20,35,56,84,120,165] 
+0

Dlaczego to jest, gdy wpisuję 'first_col = [0 ..]' (lub nawet 'n = 1') w tłumaczu, mówi' parsować błąd na wejściu '=' '? – jnylen

+3

Ach, jeśli używasz ghci, musisz poprzedzić przypisania za pomocą 'let'. Spróbuj 'let first_col = [0..1]' – perimosocordiae

6

Dodając do wspaniałej odpowiedzi perimosocordiae, języki takie jak Haskell są tak proste, że pozwalają stworzyć nieskończoną listę nieskończonych list.

Pierwszy pozwala zdefiniować operatora, który wytwarza każdy kolejny rząd:

op :: [Integer] -> [Integer] 
op = scanl1 (+) 

Jak wyjaśnił perimosocordiae, to jest po prostu leniwy suma uruchomiony.

Musimy również przypadek bazowy:

tnBase :: [Integer] 
tnBase = [0..] 

Jak więc uzyskać nieskończoną listę liczb nieskończonych wykazów czworościennych? Mamy iteracji tej operacji w przypadku bazowego, a następnie wyjście wyprodukowane przez przypadek bazowy, to wyjścia ...

tn = iterate op tnBase 

iterate jest Preludium takie funkcje można znaleźć za pomocą hoogle i searching by name (jeśli masz dobre przypuszczenie) lub type signature (zazwyczaj znasz podpis potrzebnego ci). Source code jest zwykle połączony z haddock documentation.

Prezentacja

(w przypadku, gdy nie są wygodne z mapą, wziąć, kropli i głowy)

To wszystko jest dobrze, ale raczej bezużyteczny, jeśli nie wiem jak aby uzyskać pierwszą nieskończoną listę, aby zobaczyć drugą, trzecią itd.Istnieje wiele opcji, za to coraz konkretną listę można upuścić kilka pierwszych:

getNthTN n = head (drop n tn) 

Pierwsze kilka pierwszych wyników każdej listy jest prawdopodobnie bardziej czego szukasz mimo:

printFirstFew n m = print $ take m (map (take n) tn) 

Tutaj przyjmie pierwsze wartości n z każdej listy liczb tetraedrycznych, podczas gdy take m ograniczy nasze wyniki do pierwszych list m.

I wreszcie, podoba mi się niesamowite groom pakiet dla szybkiego interaktywnej gry z danymi:

> groom $ take 10 (map (take 10) tn) 
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45], 
[0, 1, 4, 10, 20, 35, 56, 84, 120, 165], 
[0, 1, 5, 15, 35, 70, 126, 210, 330, 495], 
[0, 1, 6, 21, 56, 126, 252, 462, 792, 1287], 
[0, 1, 7, 28, 84, 210, 462, 924, 1716, 3003], 
[0, 1, 8, 36, 120, 330, 792, 1716, 3432, 6435], 
[0, 1, 9, 45, 165, 495, 1287, 3003, 6435, 12870], 
[0, 1, 10, 55, 220, 715, 2002, 5005, 11440, 24310], 
[0, 1, 11, 66, 286, 1001, 3003, 8008, 19448, 43758]] 
+0

Obie dobre odpowiedzi, dzięki! – jnylen

Powiązane problemy