2012-03-17 9 views
5

Czy istnieje sposób na sprawdzenie statyczne tablic Haskell? Weźmy ten kod:Statyczna kontrola granic macierzy Haskell

import Data.Array 
let a = listArray (0, 10) [-3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02, 1.383577518672690e+02, -3.066479806614716e+01, 2.506628277459239e+00] 

(0, 10) powinien być naprawdę (0, 5), ale kompilator przyjmuje kodu. Błąd jest wykrywany tylko w środowisku wykonawczym, mimo że mógł zostać wykryty podczas kompilacji.

+2

Być może można go wykryć * w tym przypadku * - ** jeśli ** kompilator wykonuje wiele operacji składających i stałych, aby uzyskać bezwarunkowe wywoływanie "błędu" (lub innego). W większości nietrywialnych programów nie można go wykryć, przynajmniej nie z rozsądnym wysiłkiem. A potem pojawia się ten brzydki problem z zatrzymaniem ... – delnan

+0

Użyj [Habit] (http://hasp.cs.pdx.edu/habit-report-Nov2010.pdf) (PDF) Ix, aby uzyskać statyczną gwarancję granic. Dodatkowe punkty, jeśli przeniesiesz tę pracę do Haskell. –

+0

Jest sposób, ale zbyt niewygodny, aby być praktycznym. Aby dowiedzieć się więcej na ten temat, spróbuj przeszukać internet pod kątem "numerów typu haskell". –

Odpowiedz

7

Nie można tego wykryć podczas kompilacji, ponieważ na liście nie ma żadnych elementów, które zapisują jego rozmiar, więc funkcja listArray nie może wykonać takich sprawdzeń. Ponadto, jeśli dane pochodzą z zewnętrznego pliku (na przykład), bardzo trudno byłoby sprawdzić sprawdzenie rozmiaru statycznego.

Potrzebny jest system typu zależnego, taki jak ten, który można znaleźć w Agda, aby takie rzeczy były możliwe.

+0

To, co zostało utworzone, nie jest listą, ale tablicą (Data.Array). –

+0

Tak, ale używasz listy do utworzenia tablicy. Robisz 'listArray (start, end) someList'. – dflemstr

+0

Ale w tym kawałku kodu 'someList' jest jawnie prezentowany kompilatorowi, więc może łatwo wykonać test. Ale myślę, że rozumiem to teraz: Data.Array nie jest rodzimym typem Haskella. –