โดยทั่วไปแล้วคุณใช้อันดับที่สูงขึ้นมีหลายรูปแบบเมื่อคุณต้องการให้ผู้ถูกเรียกเพื่อให้สามารถเลือกค่าของพารามิเตอร์ชนิดที่มากกว่าโทร ตัวอย่างเช่น:
f :: (forall a. Show a => a -> Int) -> (Int, Int)
f g = (g "one", g 2)
ฟังก์ชั่นใด ๆg
ที่ผมผ่านไปนี้f
จะต้องสามารถให้ฉันInt
จากมูลค่าของบางชนิดที่เพียง แต่สิ่งที่รู้เกี่ยวกับประเภทนั้นก็คือว่ามันมีตัวอย่างของg
Show
ดังนั้นนี่คือเพียว:
f (length . show)
f (const 42)
แต่นี่ไม่ใช่:
f length
f succ
หนึ่งโปรแกรมที่มีประโยชน์โดยเฉพาะอย่างยิ่งในการใช้การกำหนดขอบเขตของประเภทการบังคับใช้การกำหนดขอบเขตของค่า สมมติว่าเรามีอ็อบเจกต์ประเภทAction<T>
ซึ่งเป็นตัวแทนการกระทำที่เราสามารถเรียกใช้เพื่อสร้างผลลัพธ์ประเภทT
เช่นอนาคตหรือการโทรกลับ
T runAction<T>(Action<T>)
runAction :: forall a. Action a -> a
ทีนี้สมมติว่าเรามีสิ่งAction
ที่สามารถจัดสรรResource<T>
วัตถุ:
Action<Resource<T>> newResource<T>(T)
newResource :: forall a. a -> Action (Resource a)
เราต้องการที่จะบังคับใช้ว่าทรัพยากรเหล่านี้จะเพียงใช้ภายในAction
ที่พวกเขาสร้างขึ้นและไม่ได้ใช้ร่วมกันระหว่างการกระทำที่แตกต่างกันหรือวิ่งที่แตกต่างกันของการกระทำเดียวกันดังนั้นการกระทำที่มีกำหนดขึ้นและทำซ้ำ
เราสามารถใช้ชนิดที่สูงขึ้นการจัดอันดับที่จะบรรลุนี้โดยการเพิ่มพารามิเตอร์S
ไปResource
และAction
ประเภทซึ่งมีทั้งหมดนามธรรมมันหมายถึง“ขอบเขต” Action
ของ ตอนนี้ลายเซ็นของเราคือ:
T run<T>(<S> Action<S, T>)
Action<S, Resource<S, T>> newResource<T>(T)
runAction :: forall a. (forall s. Action s a) -> a
newResource :: forall s a. a -> Action s (Resource s a)
ตอนนี้เมื่อเราให้เราจะมั่นใจได้ว่าเพราะ“ขอบเขต” พารามิเตอร์เป็น polymorphic อย่างเต็มที่ก็ไม่สามารถหนีร่างกายของ-So ค่าของชนิดที่ใช้ใด ๆเช่นเช่นเดียวกันไม่สามารถหลบหนี!runAction
Action<S, T>
S
runAction
S
Resource<S, int>
(ใน Haskell นี้เป็นที่รู้จักกันST
monad ที่runAction
เรียกว่าrunST
, Resource
เรียกว่าSTRef
และnewResource
ที่เรียกว่าnewSTRef
.)
let sdff = (g : (f : <T> (e : T) => void) => void) => {}