Zoeken…


Syntaxis

  • - het definiëren van een functie zonder argumenten lijkt op het eenvoudig definiëren van een waarde
    taal = "Elm"
  • - een functie zonder argumenten aanroepen door de naam te vermelden
    taal
  • - parameters worden gescheiden door spaties en volgen de naam van de functie
    voeg xy = x + y toe
  • - roep een functie op dezelfde manier aan
    voeg 5 2 toe
  • - een functie gedeeltelijk toepassen door slechts enkele van de parameters ervan te verstrekken
    ophogen = toevoegen 1
  • - gebruik de operator |> om de uitdrukking links door te geven aan de functie rechts
    tien = 9 |> ophogen
  • - de <| operator geeft de uitdrukking aan de rechterkant door aan de functie aan de linkerkant
    toename <| voeg 5 4 toe
  • - keten / stel twee functies samen met de >> operator
    backwardsYell = String.reverse >> String.toUpper
  • - de << werkt hetzelfde in omgekeerde richting
    backwardsYell = String.toUpper << String.reverse
  • - een functie met een niet-alfanumerieke naam tussen haakjes maakt een nieuwe operator aan
    (#) xy = x * y
    tien = 5 # 2
  • - elke infix-operator wordt een normale functie wanneer u deze tussen haakjes plaatst
    tien = (+) 5 5
  • - optionele type-annotaties verschijnen boven functieverklaringen
    isTen: Int -> Bool
    isTen n = if n == 10 dan Waar anders Niet waar

Overzicht

De syntaxis van de functie-applicatie in Elm maakt geen gebruik van haakjes of komma's en is in plaats daarvan witruimtegevoelig.

Om een functie te definiëren, geeft u de naam multiplyByTwo en argumenten x , alle bewerkingen na is gelijk aan = is wat wordt geretourneerd door een functie.

multiplyByTwo x =
    x * 2

Om een functie aan te roepen, geeft u de naam en argumenten op:

multiplyByTwo 2  -- 4

Merk op dat syntaxis zoals multiplyByTwo(2) niet nodig is (hoewel de compiler niet klaagt). De haakjes dienen alleen om voorrang op te lossen:

> multiplyByTwo multiplyByTwo 2
-- error, thinks it's getting two arguments, but it only needs one

> multiplyByTwo (multiplyByTwo 2)
4 : number

> multiplyByTwo 2 + 2
6 : number
-- same as (multiplyByTwo 2) + 2

> multiplyByTwo (2 + 2)
8 : number

Lambda-uitdrukkingen

Elm heeft een speciale syntaxis voor lambda-expressies of anonieme functies:

\arguments -> returnedValue

Bijvoorbeeld, zoals te zien in List.filter :

> List.filter (\num -> num > 1) [1,2,3]
[2,3] : List number

Meer diepgaand wordt een achterwaartse schuine streep, \ , gebruikt om het begin van lambda-expressie te markeren, en de pijl, -> , wordt gebruikt om argumenten af te bakenen uit de hoofdtekst. Als er meer argumenten zijn, worden deze gescheiden door een spatie:

normalFunction x y = x + y
-- is equivalent to
lambdaFunction = \x y -> x + y

> normalFunction 1 2
3 : number

> lambdaFunction 1 2
3 : number

Lokale variabelen

Het is mogelijk om lokale variabelen in een functie te definiëren

  • verminder herhaling van code
  • geef naam aan subexpressies
  • verminder het aantal doorgegeven argumenten.

De constructie hiervoor is let ... in ...

bigNumbers =
    let
        allNumbers =
            [1..100]

        isBig number =
            number > 95
    in
        List.filter isBig allNumbers

> bigNumbers
[96,97,98,99,100] : List number

> allNumbers
-- error, doesn't know what allNumbers is!

De volgorde van definities in het eerste deel van let doet er niet toe!

outOfOrder =
    let
        x =
            y + 1  -- the compiler can handle this

        y =
            100
    in
        x + y

> outOfOrder
201 : number

Gedeeltelijke toepassing

Gedeeltelijke toepassing betekent het aanroepen van een functie met minder argumenten dan het heeft en het resultaat opslaan als een andere functie (die wacht op de rest van de argumenten).

multiplyBy: Int -> Int -> Int    
multiplyBy x y =
    x * y


multiplyByTwo : Int -> Int  -- one Int has disappeared! we now know what x is.
multiplyByTwo =
    multiplyBy 2


> multiplyByTwo 2
4 : Int

> multiplyByTwo 4
8 : Int

Als academische sidenote kan Elm dit doen door achter de schermen te curren .

Strikte en vertraagde evaluatie

In iep wordt de waarde van een functie berekend wanneer het laatste argument wordt toegepast. In het onderstaande voorbeeld wordt de diagnose uit het log afgedrukt wanneer f wordt aangeroepen met 3 argumenten of wordt een gecurryde vorm van f toegepast met het laatste argument.

import String
import Debug exposing (log)

f a b c = String.join "," (log "Diagnostic" [a,b,c]) -- <function> : String -> String -> String -> String

f2 = f "a1" "b2" -- <function> : String -> String

f "A" "B" "C"
-- Diagnostic: ["A","B","C"]
"A,B,C" : String

f2 "c3"
-- Diagnostic: ["a1","b2","c3"]
"a1,b2,c3" : String

Soms wil je voorkomen dat een functie meteen wordt toegepast. Een typisch gebruik in iep is Lazy.lazy dat een abstractie biedt voor het regelen wanneer functies worden toegepast.

lazy : (() -> a) -> Lazy a

Luie berekeningen hebben een functie van één () of Unit argument. Het eenheidstype is conventioneel het type van een argument voor tijdelijke aanduiding. In een lijst met argumenten wordt het bijbehorende argument gespecificeerd als _ , wat aangeeft dat de waarde niet wordt gebruikt. De eenheidswaarde in iep wordt aangegeven door het speciale symbool () dat conceptueel een lege tuple of een hole kan vertegenwoordigen. Het lijkt op de lege lijst met argumenten in C, Javascript en andere talen die haakjes gebruiken voor functieaanroepen, maar het is een normale waarde.

In ons voorbeeld kan f worden beschermd tegen onmiddellijk evalueren met een lambda:

doit f = f () -- <function> : (() -> a) -> a
whatToDo = \_ -> f "a" "b" "c" -- <function> : a -> String
-- f is not evaluated yet

doit whatToDo
-- Diagnostic: ["a","b","c"]
"a,b,c" : String

Functie-evaluatie wordt vertraagd wanneer een functie gedeeltelijk wordt toegepast.

defer a f = \_ -> f a -- <function> : a -> (a -> b) -> c -> b

delayF = f "a" "b" |> defer "c" -- <function> : a -> String

doit delayF
-- Diagnostic: ["a","b","c"]
"a,b,c" : String

Elm heeft een always functie, die niet kan worden gebruikt om de evaluatie uit te stellen. Omdat iep alle functieargumenten evalueert, ongeacht of en wanneer het resultaat van de functie-toepassing wordt gebruikt, zal het inpakken van een functie-toepassing always geen vertraging veroorzaken, omdat f always als parameter volledig wordt toegepast.

alwaysF = always (f "a" "b" "c") -- <function> : a -> String
-- Diagnostic: ["a","b","c"] -- Evaluation wasn't delayed.

Infix-operators en infix-notatie

Elm staat de definitie van aangepaste infix-operatoren toe.

Infix-operatoren worden gedefinieerd met behulp van haakjes rond de naam van een functie.

Beschouw dit voorbeeld van infix-operator voor constructie Tuples 1 => True -- (1, True) :

(=>) : a -> b -> ( a, b )
(=>) a b =
    ( a, b )

De meeste functies in Elm worden gedefinieerd in de prefixnotatie.

Pas elke functie toe met behulp van infixnotatie door het eerste argument op te geven vóór de functienaam omsloten door een ernstig accentteken:

import List exposing (append)


append [1,1,2] [3,5,8]   -- [1,1,2,3,5,8]
[1,1,2] `append` [3,5,8] -- [1,1,2,3,5,8]


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow