53

Przeczytałem, że system typu Scala jest osłabiony przez interoperacyjność Javy i dlatego nie może wykonywać niektórych z tych samych uprawnień, co system typu Haskella. Czy to prawda? Czy słabość wynika z rodzaju wymazania, czy też jestem w błędzie pod każdym względem? Czy ta różnica jest powodem, dla którego Scala nie ma typografii?Wady systemu typu Scala kontra Haskell?

+1

Możesz chcieć to przeczytać. http://lambda-the-ultimate.org/taxonomy/term/32 –

+4

Jestem prawie pewien, że Haskell ma co najmniej tyle samo wymazania co Scala, bo to jest warte tego. –

Odpowiedz

51

Główna różnica polega na tym, że Scala nie ma globalnego typu indeksu typu Hindley-Milner, a zamiast tego korzysta z postaci lokalnej typu wnioskowania, wymagającej określenia typów parametrów metod i typu zwracanego dla funkcji przeciążonych lub rekursywnych.

Nie jest to spowodowane wyłączeniem typu lub innymi wymaganiami JVM. Wszystkie możliwe trudności tutaj mogą zostać przezwyciężone i zostały, po prostu, rozważmy - Wnioskowanie H-M nie działa w kontekście obiektowym. W szczególności, gdy stosuje się polimorfizm typu (w przeciwieństwie do polimorfizmu ad-hoc w klasach typu). Ma to zasadnicze znaczenie dla silnej współpracy z innymi bibliotekami Java i (w mniejszym zakresie) w celu uzyskania najlepszej możliwej optymalizacji z JVM.

Nie można powiedzieć, że Haskell lub Scala mają silniejszy system typów, tylko że są różne. Oba języki przesuwają granice dla programowania opartego na typie w różnych kierunkach, a każdy język ma unikalne mocne strony, które trudno powielić w drugim.

+0

Rozdział 16 demonstruje typy danych i dopasowywanie wzorców Scala, rozwijając system wnioskowania typu w stylu H/M http: //www.scala -lang.org/docu/files/ScalaByExample.pdf – oluies

+4

"Wnioskowanie HM nie działa w kontekście obiektowym". Ale F # implementuje H-M i ma stronę zorientowaną obiektowo. –

+10

@Mauricio: Tak, a OCaml jest jeszcze lepszym przykładem licznika, ponieważ podaje typy klas ... –

13

Kolejnym interesującym punktem do rozważenia jest to, że Scala bezpośrednio obsługuje klasyczny styl OO. Co oznacza, że ​​istnieją relacje podtypu podtypu (np. Lista jest podklasą Seq). A to sprawia, że ​​wnioskowanie typu jest trudniejsze. Dodaj do tego fakt, że możesz mieszać cechy w Scali, co oznacza, że ​​dany typ może mieć wiele relacji nadtypowych (czyniąc go jeszcze trudniejszym)

8

Mam tylko małe experenice z Haskellem, ale najbardziej oczywiste jest to, że zwróć uwagę, że typem Scala różnym od Haskella jest typ wnioskowania.

W programie Scala nie ma globalnego typu wnioskowania, należy wyraźnie podać typ argumentów funkcji.

Na przykład w Scala trzeba napisać tak:

def add (x: Int, y: Int) = x + y 

zamiast

add x y = x + y 

Może to powodować problemy, gdy trzeba generyczną wersję funkcji dodać, że działa ze wszystkimi rodzajami typu ma metodę "+". Istnieje obejście tego problemu, ale będzie ono bardziej szczegółowe.

Ale w prawdziwym użyciu znalazłem system typu Scala jest wystarczająco potężny do codziennego użytku i prawie nigdy nie używam tego obejścia dla ogólnego, może dlatego, że pochodzę ze świata Java.

Ograniczenie jawności zadeklarowania rodzaju argumentów nie jest konieczne, ale trzeba to udokumentować.

23

System typu Scala różni się od systemu Haskella, chociaż koncepcje Scala są czasami bezpośrednio inspirowane przez mocne strony Haskella i jego kompetentną społeczność naukowców i profesjonalistów.

Oczywiście uruchamianie na maszynie wirtualnej, która nie jest przeznaczona przede wszystkim do programowania funkcjonalnego, stwarza pewne problemy ze zgodnością z istniejącymi językami docelowymi dla tej platformy. Ponieważ większość rozumowań dotyczących typów występuje w czasie kompilacji, ograniczenia Java (jako języka i platformy) w czasie wykonywania nie stanowią problemu (z wyjątkiem Type Erasure, chociaż dokładnie ten błąd wydaje się integrować z Ekosystem Java jest bardziej płynny).

O ile mi wiadomo, jedynym "kompromisem" na poziomie systemu typu z Javą jest specjalna składnia do obsługi typów Raw. Scala nawet nie zezwala już na Raw Type, ale akceptuje starsze pliki klasy Java z tym błędem. Może widziałeś kod taki jak List[_] (lub dłuższy odpowiednik List[T] forSome { type T }). Jest to funkcja kompatybilności z Javą, ale jest wewnętrznie traktowana jako typ egzystencjalny i nie osłabia systemu typów.

System typu Scala obsługuje type classes, chociaż w bardziej szczegółowy sposób niż Haskell.Sugeruję przeczytanie tego artykułu, co może stworzyć inne wrażenie na względnej sile systemu typu Scala (tabela na stronie 17 służy jako fajna lista bardzo potężnych koncepcji systemów typu).

Niekoniecznie związane z potęgą systemu typu jest podejście Scala i kompilatory Haskella do wnioskowania typów, chociaż ma to pewien wpływ na sposób, w jaki ludzie piszą kod. Posiadanie potężnego algorytmu wnioskowania może sprawić, że warto napisać bardziej abstrakcyjny kod (możesz sam zdecydować, czy to dobrze we wszystkich przypadkach).

W końcu systemy typu Scala i Haskell są napędzane chęcią zapewnienia swoim użytkownikom najlepszych narzędzi do rozwiązania ich problemów, ale podjęły różne ścieżki do tego celu.

+0

+1 za wzmiankę o tym stole. –

+3

Typy egzystencjalne to nie to samo, co typy surowe. Na przykład lista [_] nie jest uznawana za typ równy innej liście [_] –

6

Czy są one podatne na redukcję?

Zobacz stronę Olega Kiselyova http://okmij.org/ftp/ ... Można wprowadzić rachunek lambda w systemie typu Haskella. Jeśli Scala może to zrobić, to w pewnym sensie system typu Haskella i system typu Scala obliczają te same typy. Pytania brzmią: Jak naturalny jest jeden nad drugim? Jak elegancki jest jeden nad drugim?