5

W co najmniej niektórych językach rodziny ML można zdefiniować rekordy, w których można wykonać dopasowywanie wzorców, np. http://learnyouahaskell.com/making-our-own-types-and-typeclasses - podstawową ideą jest zdefiniowanie typu rekordu z nazwanymi polami, konstruktor jest automatycznie tworzony z tymi polami jako parametrami, dzięki czemu można tworzyć rekordy tego typu, a ekstraktor jest automatycznie tworzony z tymi polami jako parametrami, dzięki czemu można uzyskać wzór dopasuj do rekordów tego typu.Tylko język Scala z przeciążonymi ekstraktorami?

Scala idzie o krok dalej i pozwala oddzielić od siebie pola przechowywane w rekordzie, parametry konstruktora i parametry ekstraktora, np. http://daily-scala.blogspot.com/2009/11/overloaded-unapply.html - w tym jest realizacja celu polegającego na wspieraniu programowania obiektowego i funkcjonalnego. (Języki zorientowane obiektowo oczywiście pozwalają na oddzielenie przechowywanych pól i parametrów konstruktora, chociaż zwykle nie posiadają ekstraktorów.)

Czy istnieją inne języki, które mają dopasowanie do wzorca i umożliwiają takie oddzielenie?

Czy napisano coś o zaletach i wadach takiego oddzielenia?

+0

Haskell jest językiem rodzina ML? – millimoose

+4

Nigdy ich nie używam, ale widoki Haskella są podobne – Owen

+0

Oczywiście, języki dynamiczne, takie jak Scheme, pozwalają na to bez wsparcia językowego, ale nie wiem, czy ktokolwiek z nich korzysta – Owen

Odpowiedz

9

Przyznaję, że nie mam 100% wiedzy niezbędnej do zrozumienia Twojego pytania, ale mogę powiedzieć, że F # ma funkcję o nazwie "Active Patterns", która prawdopodobnie mogłaby zostać wykorzystana do zbudowania tej samej funkcjonalności, co Twoja daily-scala link demonstruje.

Czy to w pobliżu tego, czego szukasz?

5

Nie, F # zapewnia tę funkcję.

Przykłady w drugim artykule mogą być realizowane z wykorzystaniem Partial Active Patterns:

let (|String|_|) = function "s" -> Some "yay" | _ -> None 
let (|Int|_|) = function 1 -> Some "hmm" | _ -> None 

let (|StringList|_|) = function "x" -> Some [1; 2; 3] | _ -> None 
let (|IntList|_|) = function 1 -> Some ["one"; "two"] | _ -> None 

match 1 with 
| Int s -> printfn "%O" s 
| _ -> printfn "Unmatched" 

match "s" with 
| String s -> printfn "%O" s 
| _ -> printfn "Unmatched" 

match "x" with 
| StringList [x; y; z] -> printfn "%O" (x, y, z) 
| _ -> printfn "Unmatched" 

match 1 with 
| IntList [x; y] -> printfn "%O" (x, y) 
| _ -> printfn "Unmatched" 

Aktywni Patterns jest potężną techniką, można nawet napisać go w recursive sposób. Jego połączenie z dopasowywaniem wzorców zapewnia wygodny zestaw narzędzi do niszczenia danych. Dopasowywanie wzorców jest jednak niewystarczające, więc musisz użyć symbolu wieloznacznego (_) jako ostatniego wzorca.

4

Istnieje długa historia wzory pierwszej klasy wpisywanych w językach funkcjonalnych.

W kraju Haskell używamy rozszerzenia -XViewPatterns dla programowych wzorów.

Pierwszy prawdziwy obraz stanie wrócić do 1987 papierze Phila Wadler w sprawie views

Powiązane problemy