Wie Telastyn sagte: Technisch gesehen ja, es sei denn, es gibt einen Weg in Ihrer Sprache, um sicherzustellen, dass die Eingabefunktion auch rein ist.
Das ist nicht hypothetisch, es gibt in der Tat gute Möglichkeiten, dies zu garantieren. Zumindest in einer stark typisierten Sprache.
So eine reine ~ Funktion würden Sie in JavaScript als schreiben
function foo(f) {
return f(1) + 2;
}
kann direkt nach Haskell übersetzt werden:
foo :: (Int -> Int) -> Int
foo f = f 1 + 2
Jetzt können Sie in JavaScript böse Dinge tun wie
js> foo (function(x) {console.log("muharhar"); return 0})
muharhar
2
Dies ist in Haskell nicht möglich . Der Grund dafür ist, dass etwas nebenwirkungsreiches console.log()immer einen Ergebnistyp haben muss IO something, nicht nur somethingalleine.
GHCi> foo (\x -> print "muarhar" >> return 0)
<interactive>:7:12:
Couldn't match expected type ‘Int’ with actual type ‘IO b0’
In the expression: print "muarhar" >> return 0
In the first argument of ‘foo’, namely
‘(\ x -> print "muarhar" >> return 0)’
In the expression: foo (\ x -> print "muarhar" >> return 0)
Für diesen Ausdruck typecheck, müssten wir geben foodie Art Unterschrift
foo :: (Int -> IO Int) -> Int
Es stellt sich aber heraus, dass ich es dann nicht mehr implementieren kann: Da die Argumentfunktion IOdas Ergebnis hat, kann ich es nicht innerhalb verwenden foo.
<interactive>:8:44:
Couldn't match expected type ‘Int’ with actual type ‘IO Int’
In the first argument of ‘(+)’, namely ‘f 1’
In the expression: f 1 + 2
Die einzige Möglichkeit, in der ich eine IOAktion verwenden könnte, fooist, wenn das Ergebnis von fooden Typ IO Intselbst hat:
foo :: (Int -> IO Int) -> IO Int
foo f = do
f1 <- f 1
return (f1 + 2)
Aber an dieser Stelle wird aus der Signatur deutlich, foodass es sich auch nicht um eine reine Funktion handelt.
foo = function(function bar){ print(bar.toString()) }