ตามที่ Telastyn กล่าวไว้ว่าในทางเทคนิคแล้วใช่เว้นแต่จะมีวิธีในภาษาของคุณที่จะรับประกันว่าฟังก์ชั่นการป้อนข้อมูลนั้นยังบริสุทธิ์
นั่นไม่ใช่ข้อสมมุติมีวิธีที่ดีที่จะรับประกันสิ่งนี้ อย่างน้อยก็ในภาษาที่พิมพ์ออกมาอย่างรุนแรง
ฟังก์ชั่น pure ~ ที่คุณเขียนด้วยจาวาสคริปต์ในฐานะ
function foo(f) {
return f(1) + 2;
}
สามารถแปลโดยตรงสู่ Haskell:
foo :: (Int -> Int) -> Int
foo f = f 1 + 2
ตอนนี้ใน JavaScript คุณสามารถทำสิ่งชั่วร้ายเช่น
js> foo (function(x) {console.log("muharhar"); return 0})
muharhar
2
นี้เป็นไปไม่ได้ใน Haskell เหตุผลอะไรบางอย่างที่มีผลข้างเคียง - ful เช่นconsole.log()
จะต้องมีประเภทของผลเสมอIO something
ไม่เพียง แต่something
คนเดียว
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)
สำหรับนิพจน์นี้เพื่อพิมพ์เช็คเราจะต้องให้foo
ลายเซ็นประเภท
foo :: (Int -> IO Int) -> Int
แต่มันกลับกลายเป็นว่าฉันไม่สามารถใช้มันได้อีกต่อไปแล้ว: เนื่องจากฟังก์ชั่นการโต้แย้งมีIO
ผลทำให้ฉันไม่สามารถใช้มัน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
วิธีเดียวที่ฉันสามารถใช้การIO
กระทำfoo
คือถ้าผลลัพธ์ของตัวเองfoo
พิมพ์IO Int
:
foo :: (Int -> IO Int) -> IO Int
foo f = do
f1 <- f 1
return (f1 + 2)
แต่ ณ จุดนี้มันชัดเจนจากลายเซ็นของfoo
ว่ามันไม่ได้เป็นฟังก์ชั่นที่บริสุทธิ์เช่นกัน
foo = function(function bar){ print(bar.toString()) }