2012-02-10 12 views
7

Pisałem rosnącą bazę kodów w Haskell. Mój problem polega na tym, że dodałem podpisy typów do funkcji opartych na tym, co GHCI mówi mi, że powinny być.Jak zachować elastyczność pisania w języku Haskella?

Problem polega na tym, że mam coraz większy zasięg kodu, jak tylko zmieniam jedną rzecz, mój kod rozbija się w każdym miejscu i jestem pochłonięty śledzeniem wszystkich problemów.

Czy typy uzyskiwane przez ładowanie modułu w ghci są zbyt szczegółowe? Jak mogę zdecydować, jakiego typu lub klasy użyć w moich podpisach, aby wykorzystać moc silnego pisania z pewną elastycznością? (tj. nie spędzać godziny propagując drobne zmiany?).

+4

To wydaje się nieco dziwne. Co dokładnie robisz, co łamie cały kod? Czy ciągle zmieniasz swoje typy? Zwykle po pewnym czasie (lub nawet na początku) można by było naprawić jeden projekt dla jego typów, a większość pracy dotyczyłaby pozostałej części kodu (która w odpowiednio napisanym Haskella powinna być zdumiewająco niezależna). Zauważ również, że jeśli dodajesz konstruktory do swojego typu, nie jest zaskakujące, że kod, który obsługuje ten typ, łamie się, a kompilator jest pomocny w wskazywaniu potencjalnych problemów, chociaż generics może pomóc, jeśli nie może złamać kodu. .. – Jedai

+5

Być może trzeba wprowadzić pewne synonimy lub definicje typów, aby zmiany można było zlokalizować w jednym miejscu? – augustss

+2

Czy możesz podać przykład tego, co próbujesz osiągnąć i jak możesz się spodziewać zachowania? – ondra

Odpowiedz

7

Problem jest teraz, że mam ciągle codebase, jak tylko zmienić jedną rzecz, mój kod łamie wszędzie i jestem pochłonięty tropienie wszystkich problemów.

to faktycznie reklamowane jako funkcji w jesod (ramy web Haskell). Załóżmy, że mam określony następującą specyfikację routingu:

/blog/#String   BlogR GET 

I zdecydować chcę go zmienić na

/blog/#Date/#String BlogR GET 

Tak szybko, jak dokonać tej zmiany trasy, kompilator powie mi, że wszędzie Złamałem mój kod. Będę musiał zaktualizować funkcję getBlogR - zmieniając jej typ wejścia, aby akceptować także Date. Będę również zmuszony do aktualizacji dowolnego miejsca, w którym będę używał bezpiecznych adresów URL w moich szablonach, które wyglądałyby jak @{BlogR (slug p)} -> .

ten jest uważany za Dobra Rzecz, ponieważ kontroler typ jest pomagając można znaleźć problemy wprowadzone przez zmiany.


Teraz, w odniesieniu do ghci.

ghci> let shew = show 
ghci> :t shew 
shew ::() -> String 
ghci> :t show 
show :: Show a => a -> String 

Czasami prawdą jest, że ghci wybiera denerwujące wartości domyślne. To jednak można złagodzić.

ghci> :set -XNoMonomorphismRestriction 
ghci> let shew = show 
ghci> :t shew 
shew :: Show a => a -> String 

Podczas korzystania ghci odkryć rodzaj funkcji jest idealne dla początkujących, nie polecam opierając na ghci. Dowiedz się, co oznaczają podpisy typu i jak je odkryć. W rzeczywistości zacznij pisać funkcję, pisząc najpierw podpis typu, który chcesz mieć. Aby nauczyć się tej umiejętności, wystarczy niewielka inwestycja czasu i jest to wielkie ułatwienie w programowaniu, gdy możesz użyć systemu typu Haskell na swoją korzyść.

+1

Powiedziawszy to wszystko, prawdziwa odpowiedź na twoje pytanie jest prawdopodobnie sugerowana przez Augustssa: wpisz synonimy i definicje typów, aby oczyścić swój kod. –

+0

Awesome! Mój problem polega na tym, że system typów jest tak złożony, że dla początkującego najlepiej zgaduję, co podpiszę, i ostatecznie pytam ghci. (Moje bieżące problemy dotyczą liczby typów). – Toymakerii

+0

Czy istnieje sposób na przekazanie GHCI lub programu lintującego do porównania moich definicji z twardą definicją z wersją lepszą, bardziej ogólną? – Toymakerii