Chciałbym wiedzieć, jak działają typy członków w Scali i jak powinnam powiązać typy.Parametry typu a typy członków w Scali
Jednym ze sposobów jest uczynienie skojarzonego typu parametrem typu. Zaletami tego podejścia jest to, że mogę przepisać wariancję typu i mogę być pewien, że podtyp nie zmienia typu. Wady polegają na tym, że nie mogę wywnioskować parametru typu z typu w funkcji.
Drugie podejście polega na uczynieniu powiązanego typu członem drugiego typu, który ma problem z tym, że nie mogę określić granic powiązanych typów podtypów i dlatego nie mogę użyć typu w parametrach funkcji (jeśli x x x o * nie może być w żadnym związku z Xt)
Konkretnym przykładem może być:
mam cechę dla DFAS (może być bez parametru typu)
trait DFA[S] { /* S is the type of the symbols in the alphabet */
trait State { def next(x : S); }
/* final type Sigma = S */
}
i chcę utworzyć funkcję do biegania to DFA nad sekwencji wejściowej i chcę
- funkcja musi brać niczego
<% Seq[alphabet-type-of-the-dfa]
jak typ sekwencji wejściowych - rozmówca funkcja nie musi określić parametry typu, wszystko musi być wyprowadzone
- ja podobnie jak funkcja, która ma być wywołana z konkretnym typem DFA (ale jeśli istnieje rozwiązanie, w którym funkcja nie ma parametru typu dla DFA, jest OK), to typy alfabetu muszą być nieograniczone (tj. musi istnieć DFA na Char, jak również jeszcze nieznanych klasy zdefiniowanej przez użytkownika)
- DFAS z różnymi rodzajami alfabetu nie są podtypy
Próbowałem to:
def runDFA[S, D <: DFA[S], SQ <% Seq[S]](d : D)(seq : SQ) = ....
to działa , z wyjątkiem typu S nie jest tu wywnioskowana, więc muszę napisać listę parametrów całego typu na każdej stronie wywołania.
def runDFA[D <: DFA[S] forSome { type S }, SQ <% Seq[D#Sigma]](... same as above
to nie działa (nieprawidłowy okrągły odniesienie do typu D ??? (co to jest?))
ja również usunięty parametr typu, stworzony abstrakcyjny typ Sigma i próbował wiązanie tego typu w konkretnych klasach. runDFA wyglądałby
def runDFA[D <: DFA, SQ <% Seq[D#Sigma]](... same as above
ale to nieuchronnie prowadzi do problemów, takich jak "niedopasowanie typu: oczekuje dfa.Sigma
, dostał D#Sigma
"
Jakieś pomysły? Wskaźniki?
Edit:
W odpowiedzi wskazują brak jest prosty sposób to zrobić, ktoś mógłby opracować więcej o tym, dlaczego jest to niemożliwe, a co będzie musiał być zmieniony tak to działało?
powodów, dla których chcą runDFA RO być bezpłatna funkcja (nie metoda) jest to, że chcę inne podobne funkcje, jak na automatach minimalizacji, regularnych operacji językowych, NFA-to-DFA konwersji, język faktoryzacji itp i spełniające wszystkie to wewnątrz jednej klasy jest sprzeczne z prawie każdą zasadą projektowania OO.
Wow, myślałem, że masz na myśli to: http://www.huygens-fokker.org/scala/ – MusiGenesis