Masz rację, że korespondencja Curry-Howard jest bardzo ogólna. Warto zapoznać się nieco z jego historią: http://en.wikipedia.org/wiki/Curry-Howard_correspondence
Zauważysz, że jak pierwotnie sformułowano, ta korespondencja dotyczyła w szczególności intuicyjnej logiki z jednej strony, a po prostu typowego rachunku lambda (STLC) z drugiej.
Klasyczny Haskell - albo z wersji 98, albo nawet wcześniejszej, bardzo ściśle przestrzegał STLC, i w przeważającej części było bardzo proste, bezpośrednie tłumaczenie między dowolnym wyrażeniem w Haskell i odpowiednim terminem w STLC (rozszerzone o rekurencję i kilka prymitywnych typów). Czyniło to Curry-Howarda bardzo wyraźnym. Dziś dzięki rozszerzeniom takie tłumaczenie jest nieco trudniejsze.
W pewnym sensie więc pytanie brzmi, dlaczego Haskell tak łatwo „zapuszcza się” w STLC. Przychodzą mi na myśl dwie rzeczy:
- Rodzaje W przeciwieństwie do Scheme, który jest także swego rodzaju cukrowym rachunkiem lambda (między innymi), Haskell jest mocno wpisany. Oznacza to, że nie istnieją terminy w klasycznym języku Haskell, które z definicji nie mogą być dobrze wpisanymi terminami w STLC.
- Czystość. Ponownie, w przeciwieństwie do Schematu, ale podobnie jak STLC, Haskell jest czystym, referencyjnie przejrzystym językiem. To jest dość ważne. Języki z efektami ubocznymi mogą być osadzone w językach, które nie powodują skutków ubocznych. Jest to jednak transformacja całego programu, a nie tylko lokalne usuwanie. Aby mieć bezpośrednią korespondencję, konieczne jest, aby zacząć od czysto funkcjonalnego języka.
Istnieje również ważny sposób, w jaki Haskell, podobnie jak większość języków, zawodzi w odniesieniu do bezpośredniego zastosowania korespondencji Curry-Howard. Haskell, jako kompletny język Turinga, zawiera możliwość nieograniczonej rekurencji, a co za tym idzie, braku wypowiedzenia. STLC nie ma operatora punktu stałego, nie jest kompletny w turingu i silnie normalizuje się - co oznacza, że żadna redukcja terminu w STLC nie zakończy się. Możliwość rekurencji oznacza, że można „oszukać” Curry-Howarda. Na przykład let x = x in x
ma typforall a. a
- tzn. ponieważ nigdy nie powraca, mogę udawać, że daje mi wszystko! Ponieważ zawsze możemy to zrobić w Haskell, oznacza to, że nie możemy w pełni „uwierzyć” w żaden dowód odpowiadający programowi Haskell, chyba że mamy osobny dowód, że sam program się kończy.
Linia programowania funkcjonalnego przed Haskellem (zwłaszcza rodzina ML) była wynikiem badań CS koncentrujących się na budowaniu języków, w których można łatwo udowodnić (między innymi) rzeczy, badania bardzo świadome i pochodzące z CH na początek. I odwrotnie, Haskell służył zarówno jako język hosta, jak i inspiracja dla wielu asystentów w trakcie opracowywania, takich jak Agda i Epigram, które są zakorzenione w rozwoju teorii typów, bardzo związanej z rodowodem CH.