2017-03-19 7 views
3

Ich bin kürzlich auf dieses seltsame Problem in Haskell gestoßen. Der folgende Code soll einen Wert zurück auf einen Bereich abgespeckte (wenn es über high ist sollte es high zurück, wenn es unter low ist sollte es low zurückkehrenHaskell verwirrt Int mit Int -> Int

inRange :: Int -> Int -> Int -> Int 
inRange low high = max low $ min high 

die Fehlermeldung:.

scratch.hs:2:20: 
    Couldn't match expected type ‘Int -> Int’ with actual type ‘Int’ 
    In the expression: max low $ min high 
    In an equation for ‘inRange’: inRange low high = max low $ min high 

scratch.hs:2:30: 
    Couldn't match expected type ‘Int’ with actual type ‘Int -> Int’ 
    Probable cause: ‘min’ is applied to too few arguments 
    In the second argument of ‘($)’, namely ‘min high’ 
    In the expression: max low $ min high 

Sollte es nicht ein anderes Argument nehmen und es auf Hoch setzen? Ich habe bereits andere Möglichkeiten ausprobiert wie:

und

\x -> max low $ (min high x) 

Wenn es in GHCI versuche ich die folgende Fehlermeldung erhalten:

<interactive>:7:5: 
    Non type-variable argument in the constraint: Num (a -> a) 
    (Use FlexibleContexts to permit this) 
    When checking that ‘inRange’ has the inferred type 
     inRange :: forall a. 
       (Num a, Num (a -> a), Ord a, Ord (a -> a)) => 
       a -> a 

Antwort

12

($) ist definiert als:

f $ x = f x 

So Ihr Beispiel ist eigentlich:

max low (min high) 

, die falsch ist, weil man eigentlich

max low (min high x) 

Verwendung von Funktions Zusammensetzung wollen, die wie folgt definiert ist:

f . g = \x -> f (g x) 

und Ihre Arbeitsbeispiel \x -> max low (min high x) erhalten wir:

\x -> max low (min high x) 
== max low . min high -- by definition of (.)