19

Właśnie się zastanawiałem, czy możliwe jest dopasowanie do tych samych wartości wiele razy z odpowiednimi wzorcami języków programowania funkcjonalnego (Haskell/F #/Caml).Wzór pasujący do identycznych wartości

Wystarczy pomyśleć o następującym przykładzie:

plus a a = 2 * a 
plus a b = a + b 

Pierwszy wariant będzie wywoływana, gdy funkcja jest wywoływana z dwóch podobnych wartości (które byłyby przechowywane w a).

Bardziej użyteczna aplikacja to (upraszczanie AST).

simplify (Add a a) = Mult 2 a 

Ale Haskell odrzuca te kody i ostrzega mnie o sprzecznych definicji dla a - Muszę zrobić wyraźny przypadek/IF-kontrole zamiast dowiedzieć się, czy funkcja dostał identyczne wartości. Czy istnieje jakaś sztuczka wskazująca, że ​​zmienna, którą chcę dopasować, wystąpi wiele razy?

+0

FWIW, Mathematica obsługuje to. –

Odpowiedz

39

Nazywa się to nieliniowym wzorem . Było kilka wątków na liście mailingowej o tym, nie tak dawno temu. Tutaj są dwa:

http://www.mail-archive.com/[email protected]/msg59617.html

http://www.mail-archive.com/[email protected]/msg62491.html

Konkluzja: nie jest to niemożliwe do wykonania, ale zdecydowano przeciwko dla uproszczenia.

Nawiasem mówiąc, do obejścia tego nie jest potrzebne if ani case; The (nieznacznie) czystsze sposobem jest użycie strażnika:

a `plus` b 
    | a == b = 2*a 
    | otherwise = a+b 
+0

Dzięki za linki - doskonałe – Dario

13

Nie można mieć dwóch parametrów o tej samej nazwie co oznacza, że ​​powinny one być równe, ale można użyć guards odróżnić przypadki tak:

plus a b 
    | a == b = 2 * a 
    | otherwise = a + b 

To jest bardziej elastyczny, ponieważ działa również na bardziej skomplikowane warunki niż prosta równość.

+0

Tak, znam straż, ale starałem się unikać ręcznego porównania. – Dario

+0

Skrócona nazwa firmy: http: // stackoverflow.com/questions/480769/f-matching-with-two-values ​​/ 501541 # 501541 – Dario

-1

Haskell nie robi zjednoczenia.

+4

Aby zjednoczyć potrzebne są darmowe zmienne po obu stronach. –

+1

To jest tylko równość, a nie zjednoczenie. Jak '| a, a gdy a = a -> ..'. –

0

Mam tylko spojrzał w górę wątki lista dyskusyjna podane w odpowiedzi Thomasa, a pierwszy odpowiedź w jeden z nich ma sens, i wyjaśnia, dlaczego tak "wzór" nie miałby większego sensu: co jeśli a jest funkcją? (Ogólnie nie jest możliwe sprawdzenie, czy dwie funkcje są równe.)

+0

Czy nie można po prostu ograniczyć "a" do "Eq"? – gdejohn

+0

@gdejohn, podejrzewam, że semantyka nie byłaby właściwa. Stosując definicję formy "fxx = x", można rozsądnie oczekiwać IMO, że dwa przedłożone argumenty są * tej samej wartości *, a nie tylko "równe" w sensie jakiejś typki (w przeciwnym razie nie jest nawet jasne, które z dwóch wartości 'x' powinno wrócić' f'). – Alexey

-1

Zaimplementowałem nowy funkcjonalny język programowania, który może obsługiwać nieliniowe wzorce w Haskell.

https://github.com/egison/egison

w moim języku, czynność plus napisany w sposób następujący.

(define $plus 
    (match-lambda [integer integer] 
    {[[$a ,a] (* a 2)] 
    [[$a $b] (+ a b)]})) 
Powiązane problemy