Szukaj…


Uwagi

Wyjaśnijmy kilka nieporozumień, które mogą popełnić początkujący.

Być może napotkałeś takie funkcje, jak:

max :: (Ord a) => a -> a -> a  
max m n  
  | m >= n = m  
  | otherwise = n  

Początkujący zazwyczaj wyświetlają max :: (Ord a) => a -> a -> a jako, która przyjmuje dwa argumenty (wartości) typu a i zwraca wartość typu a . Jednak tak naprawdę dzieje się tak, że max bierze jeden argument typu a i zwraca funkcję typu a -> a . Ta funkcja pobiera następnie argument typu a i zwraca końcową wartość typu a .

Rzeczywiście, max można zapisać jako max :: (Ord a) => a -> (a -> a)

Rozważ podpis typu max :

Prelude> :t max  
max :: Ord a => a -> a -> a  

Prelude> :t (max 75)  
(max 75) :: (Num a, Ord a) => a -> a  

Prelude> :t (max "Fury Road")  
(max "Fury Road") :: [Char] -> [Char]  

Prelude> :t (max "Fury Road" "Furiosa")  
(max "Fury Road" "Furiosa") :: [Char]  

max 75 i max "Fury Road" mogą nie wyglądać jak funkcje, ale w rzeczywistości są.

Zamieszanie wynika z faktu, że w matematyce i wielu innych popularnych językach programowania możemy mieć funkcje, które przyjmują wiele argumentów. Jednak w Haskell funkcje mogą przyjmować tylko jeden argument i mogą zwracać wartości takie jak a lub funkcje takie jak a -> a .

Częściowo zastosowana funkcja dodawania

Możemy użyć częściowej aplikacji do „zablokowania” pierwszego argumentu. Po zastosowaniu jednego argumentu pozostaje nam funkcja, która oczekuje jeszcze jednego argumentu przed zwróceniem wyniku.

(+) :: Int -> Int -> Int

addOne :: Int -> Int
addOne = (+) 1

Następnie możemy użyć addOne , aby dodać jeden do Int .

> addOne 5
6
> map addOne [1,2,3]
[2,3,4]

Zwracanie częściowo zastosowanej funkcji

Zwracanie częściowo zastosowanych funkcji jest jedną z technik pisania zwięzłego kodu.

add :: Int -> Int -> Int
add x = (+x)

add 5 2

W tym przykładzie (+ x) jest częściowo zastosowana funkcja. Zauważ, że drugi parametr funkcji dodawania nie musi być określony w definicji funkcji.

Wynikiem wywołania add 5 2 jest siedem.

Sekcje

Przekrój jest zwięzłym sposobem częściowego zastosowania argumentów do operatorów infix.

Na przykład, jeśli chcemy napisać funkcję, która dodaje „ing” na końcu słowa, możemy użyć sekcji do zwięzłego zdefiniowania funkcji.

> (++ "ing") "laugh"
"laughing"

Zauważ, jak częściowo zastosowaliśmy drugi argument. Zwykle możemy tylko częściowo zastosować argumenty w określonej kolejności.

Możemy również użyć lewego przekroju, aby częściowo zastosować pierwszy argument.

> ("re" ++) "do"
"redo"

Równie dobrze moglibyśmy napisać to przy użyciu częściowej aplikacji o normalnym prefiksie:

> ((++) "re") "do"
"redo"

Uwaga na temat odejmowania

Początkujący często niepoprawnie dzielą negację.

> map (-1) [1,2,3]
***error: Could not deduce...

To nie działa, ponieważ -1 jest analizowane jako literał -1 zamiast operatora podzielonego na segmenty - stosowane do 1 . Istnieje funkcja subtract celu obejścia tego problemu.

> map (subtract 1) [1,2,3]
[0,1,2]


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow