Najpierw musisz zdecydować, jak reprezentować swoją tabelę arkuszy kalkulacyjnych. Jeśli pochodzisz z tła C, możesz użyć tablicy 2D, ale odkryłem, że słownik faktycznie działa lepiej w Wiązach. Możesz więc zdefiniować type alias Grid a = Dict (Int, Int) a
.
Co do a
, co każda komórka posiada ... jest to okazja do zdefiniowania języka specyficznego dla domeny. Oznacza to, że wyrażenie jest albo literałem zmiennoprzecinkowym, odniesieniem do innej lokalizacji komórki, albo operatorem. Operator może być dowolną funkcją na dwóch elementach pływających i dwoma innymi wyrażeniami, które są rekursywnie oceniane. W zależności od tego, do czego zmierzasz, możesz zamiast tego zdefiniować specjalne znaczniki dla każdej operacji, takie jak Plus Expr Expr | Times Expr Expr
, lub możesz dodać dodatkowe tagi opN dla operacji o różnym pochodzeniu (jak negate).
Więc możesz zdefiniować type alias Spreadsheet = Grid Expr
, a jeśli chcesz, aby alias (Int, Int)
coś, może to również pomóc. Zakładam też, że chcesz tylko pływać w arkuszu kalkulacyjnym.
Teraz potrzebujesz funkcji do konwertowania łańcuchów na wyrażenia iz powrotem. Tradycyjne nazwy dla tych funkcji to parse
i eval
.
parse : String -> Maybe Expr -- Result can also work
eval : Spreadsheet -> Grid Float
evalOne : Expr -> Spreadsheet -> Maybe Float
Parsowanie będzie trochę trudne; String module jest twoim przyjacielem. Eval będzie polegał na wyszukiwaniu referencji w arkuszu kalkulacyjnym i rekursywnym wypełnianiu wyników. Na początku będziesz chciał zignorować możliwość łapania nieskończonych pętli. Ponadto jest to tylko szkic, jeśli zauważysz, że różne podpisy typów działają lepiej, użyj ich.
Jeśli chodzi o widok, zacznę od odczytu, aby można było zweryfikować, czy prawidłowo zakodowane arkusze kalkulacyjne są poprawnie obliczane. Następnie możesz się martwić o edytowanie, a pomysł polega na ponownym uruchomieniu analizatora składni i analizatora i wygenerowaniu nowego arkusza kalkulacyjnego do renderowania. Powinien działać, ponieważ arkusz kalkulacyjny nie ma stanu innego niż zawartość każdej komórki. (Minimalizacja przeliczonej pracy jest jednym z wielu sposobów na jej rozszerzenie.) Jeśli używasz elm-html, elementy tabeli powinny być w porządku.
Mam nadzieję, że to cię zmieni we właściwym kierunku. Jest to ambitny projekt i bardzo chciałbym go zobaczyć, kiedy skończysz (zamieść go na mailing list). Powodzenia!
Dziękuję za bardzo dokładną odpowiedź. Nie mogę się doczekać wypróbowania tego. Postaram się opublikować, jeśli zrobię coś pożytecznego :) – oskbor