Sök…


Anmärkningar

Låt oss rensa upp några missuppfattningar som nybörjare kan göra.

Du kan ha stött på funktioner som:

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

Nybörjare visar vanligtvis max :: (Ord a) => a -> a -> a som funktion som tar två argument (värden) av typ a och returnerar ett värde av typ a . Men vad som verkligen händer är att max tar ett argument av typ a och returnerar en funktion av typ a -> a . Denna funktion tar sedan ett argument av typ a och returnerar ett slutligt värde av typ a .

Faktum är att max kan skrivas som max :: (Ord a) => a -> (a -> a)

Tänk på typsignaturen för 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 och max "Fury Road" kanske inte ser ut som funktioner, men i själva verket är de det.

Förvirringen härrör från det faktum att i matematik och många, andra, vanliga programmeringsspråk, får vi ha funktioner som tar flera argument. Men i Haskell kan funktioner bara ta ett argument och de kan returnera antingen värden som a eller funktioner som a -> a .

Delvis tillämpad tilläggsfunktion

Vi kan använda en partiell applikation för att "låsa" det första argumentet. Efter att ha använt ett argument sitter vi kvar med en funktion som förväntar oss ytterligare ett argument innan resultatet returneras.

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

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

Vi kan sedan använda addOne för att lägga till en till en Int .

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

Återgå till en delvis tillämpad funktion

Återvända delvis tillämpade funktioner är en teknik för att skriva kort kod.

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

add 5 2

I detta exempel (+ x) är en delvis tillämpad funktion. Observera att den andra parametern till tilläggsfunktionen inte behöver specificeras i funktionsdefinitionen.

Resultatet av att ringa add 5 2 är sju.

sektioner

Sektionering är ett kortfattat sätt att delvis tillämpa argument på infixoperatörer.

Om vi till exempel vill skriva en funktion som lägger till "ing" i slutet av ett ord kan vi använda ett avsnitt för att definiera en funktion kortfattat.

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

Lägg märke till hur vi delvis har använt det andra argumentet. Normalt kan vi bara delvis tillämpa argumenten i den angivna ordningen.

Vi kan också använda vänster sektionering för att delvis tillämpa det första argumentet.

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

Vi kan på motsvarande sätt skriva detta med hjälp av normal prefix partiell applikation:

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

En anmärkning om subtraktion

Nybörjare ofta felaktigt avsnitt negation.

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

Detta fungerar inte eftersom -1 är tolkat som bokstavligt -1 snarare än den sektionsoperatör - tillämpas på 1 . subtract finns för att kringgå detta problem.

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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow