2010-12-15 14 views
43

Jeśli chcemy zmapować funkcję, która zwiększa każdy element szeregu 1, moglibyśmy napisaćcurrying odejmowanie

map (\x -> x + 1) [1..5] 

ale myślę, że większość ludzi po prostu pójść na

map (+1) [1..5] 

zamiast. Ale to oczywiście nie działa z (-1), ponieważ jest to negatywne.

Tak więc pierwszą rzeczą, która przyszła mi do głowy było

map (+(-1)) [1..5] 

które miałoby sensu biorąc pod uwagę jak odejmowanie jest zdefiniowana w Prelude (x - y = x + negate y), ale wygląda to nieco dziwne dla mnie. Potem wymyśliłem:

To wydaje mi się lepsze, ale może trochę zbyt skomplikowane.

Teraz wiem, że to nic wielkiego, ale zastanawiam się, czy brakuje mi bardziej oczywistego sposobu na napisanie tego? Jeśli nie, który z 2 sposobów chciałbyś? Naprawdę tylko pytam, ponieważ często są to drobne szczegóły, które sprawiają, że twój kod jest bardziej idiomatyczny, a przez to przyjemny dla innych programistów, którzy muszą go przeczytać.

Rozwiązanie

Teraz mam kilka odpowiedzi, myślę, że mój osobisty faworyt

map (subtract 1) [1..5] 

następnie

map pred [1..5] 

głównie dlatego, że pierwszy z nich jest bardzo wyraźny i nikt nie musi zgadywać/szukać tego, co znaczy pred (poprzednik).

+3

mała uwaga: problem nie jest currying, to składnia sekcja operator.'(-) 1' jest (syntaktycznie poprawnym) sposobem na częściowe zastosowanie funkcji curry' -'. –

+3

Walczyłem o tytuł i nie mogłem wymyślić nic lepszego. Również 'map ((-) 1) [1..5]' nie działa, stąd wersja z odwróceniem. –

+0

Jeśli są one integralne, a chcesz tylko odjąć 1, dlaczego nie 'map pred' –

Odpowiedz

38

Można użyć funkcji subtract zamiast - jeśli chcesz prawej sekcji odejmowania:

map (subtract 1) [1..5] 
+1

To był typ oczywistej rzeczy, którą miałem na myśli, dzięki! Czasami po prostu nie widać lasu dla drzew, Hoogle i wszystkich innych. –

1

myślę map (\x -> x - 1) [1..5] przekazuje intencję programisty lepiej, ponieważ nie ma wątpliwości co do tego, co jest odejmowana od czego. Również znajduję twoje pierwsze rozwiązanie, map (+(-1)) [1..5], również łatwe do odczytania.

8

Od - jest zarówno odejmowania infix i Negate przedrostek, nie można użyć (gdzie * jest operatorem Infix i x wartość) (*x) składnię -. Na szczęście Prelude pochodzi z negate i subtract, które są odpowiednio \x -> -x i \x y -> y-x, dzięki czemu można korzystać z tych, w których trzeba rozróżnić między tymi dwoma.

+0

'odjąć' to tak naprawdę' \ x y -> y - x'. – nyuszika7h

+0

@ nyuszika7h dzięki, naprawiłem to. – HaskellElephant

2

Nie podoba mi się subtract, ponieważ jest myląco wstecz. Sugeruję

minus :: Num n => n -> n -> n 
minus = (-) 
infixl 6 `minus` 

Następnie można napisać

map (`minus` 1) [1..5] 
+2

Wolę właśnie '(+ (- 1))'. Sztuczka z nową nazwą jest fajna, ale zajmuje cenne imię. Szkoda, że ​​'' ('-' 1)' 'jest nieprawidłową składnią. –