2017-01-31 2 views
2
module Tf0 where 

all' :: (a -> Bool) -> [a] -> Bool 
all' p = foldr (&&) True . map p 

main :: IO() 

xs = [1,3,5,7,9] 
xs1 = [1,3,11,4,15] 

k1 = all' (<10) xs 
k2 = all' (<10) xs1 
k3 = all' (<10) 

main = print k1 

Fragen:Haskell Funktionsdefinition, fehlendes Argument?

  1. In der Funktionsdefinition (all' p = foldr (&&) True . map p) gibt es keine Liste als eine Eingabe ist, während die Type-Funktion eine Liste als Eingang ([a]) zeigt, noch versucht, die Funktion zu überprüfen (siehe unter k1, k2, k3) zeigt, dass eine Liste benötigt wird.

  2. Wie kann die Funktion ohne die Liste definiert werden?

+1

Schreiben 'f x = g x. h x 'ist das gleiche wie das Schreiben von 'f x y = g x (h x y)', nach Definition des Kompositionsoperators '.'. Der erste Stil wird als "point-free style" (oder scherzhaft point-less style) bezeichnet. – chi

+0

Ein Wort: Curry. – chepner

Antwort

4

Einer der grundlegenden Aspekte von Haskell ist, dass konzeptionell eine Funktion immer ein Argument nimmt. nehmen in der Tat zum Beispiel die Funktion (+):

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

(technisch ist es (+) :: Num a => a -> a -> a, aber lassen Sie uns die Dinge einfach halten).

Nun können Sie argumentieren, dass (+) zwei Argumente braucht, aber konzeptionell braucht es ein Argument. Tatsächlich: ist die Signatur in der Tat

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

So füttern Sie es eine ganze Zahl und jetzt gibt es eine Funktion, zum Beispiel:

(+) 5 :: Int -> Int 

So haben Sie, indem sie ihm eine 5 geben, konstruiert eine Funktion, die einem gegebenen Operanden 5 hinzufügt (wiederum eine Funktion, die ein Argument benötigt).

Nun ist diese auf Ihre Frage angewendet wird, ist die Unterschrift von all' in der Tat:

all' :: (a -> Bool) -> ([a] -> Bool) 

Also, wenn Sie all' mit einem Argument gelten, es eine Funktion gibt, die eine Liste bildet [a] zu einem Bool. Sprich für die Zwecke der Beweisführung, die wir p-\_ -> True gesetzt, dann kehren wir zurück:

foldr (&&) True . map (\_ -> True) :: [a] -> Bool 

so in der Tat eine Funktion, die eine Liste nimmt [a] und bildet sie auf einem Bool. In einer nächsten Phase wenden Sie eine Liste an , die (zurück) -Funktion.

Mit anderen Worten, funktionale Programmierung kann als eine lange Kette der Spezialisierung einer Funktion weiter und weiter betrachtet werden, bis sie vollständig geerdet ist und ausgewertet werden kann.

Haskell bietet dies nur auf elegante Weise, so dass Sie nicht über Funktionen nachdenken müssen, die Funktionen erzeugen. Aber konzeptionell passiert dies die ganze Zeit.Gegeben Sie eine Funktion f :: a -> b -> c implementieren möchten, können Sie dies tun, wie:

f x y = g (x+1) y 

(mit g :: a -> b -> c), aber Sie können auch entscheiden, einen Parameter aus zu verlassen, und definieren es als:

seit g (x+1) wird eine Funktion zurückgeben, die mit der y schließlich gelten kann.

+1

Ich würde den Abschnitt '(5+)' dafür vermeiden, da es eine spezielle Syntax ausnutzt und stattdessen die einfache Anwendung '(+) 5' verwendet, die dem Geist des Arguments folgt. – chi

+0

@chi: das ist in der Tat ein guter Vorschlag: modifiziert. Vielen Dank. –

+0

Vielen Dank für Ihre guten Erklärungen, aber ich würde gerne eine Antwort für das Folgende bekommen: Gegeben (aus Ihrem Beispiel, dass zwei (verschiedene?) Funktionen: fxy = g (x + 1) y und fx = g (x + 1), wie funktioniert die zweite Funktion (fx = g (x + 1)) "Wissen", dass ein zweiter Parameter (y) erwartet wird? – Atir

Verwandte Themen