Nói chung, bạn sử dụng đa hình bậc cao hơn khi bạn muốn callee có thể chọn giá trị của một tham số loại, thay vì người gọi . Ví dụ:
f :: (forall a. Show a => a -> Int) -> (Int, Int)
f g = (g "one", g 2)
Bất kỳ chức năng gnào tôi chuyển đến điều này fphải có thể cung cấp cho tôi Inttừ một giá trị của một loại nào đó, trong đó điều duy nhất gbiết về loại đó là nó có một thể hiện của Show. Vì vậy, đây là kosher:
f (length . show)
f (const 42)
Nhưng đây không phải là:
f length
f succ
Một ứng dụng đặc biệt hữu ích là sử dụng phạm vi của các loại để thực thi phạm vi giá trị . Giả sử chúng ta có một đối tượng của kiểu Action<T>, đại diện cho một hành động mà chúng ta có thể chạy để tạo ra kết quả của loại T, chẳng hạn như tương lai hoặc gọi lại.
T runAction<T>(Action<T>)
runAction :: forall a. Action a -> a
Bây giờ, giả sử rằng chúng ta cũng có một đối tượng Actioncó thể phân bổ Resource<T>các đối tượng:
Action<Resource<T>> newResource<T>(T)
newResource :: forall a. a -> Action (Resource a)
Chúng tôi muốn thực thi rằng các tài nguyên đó chỉ được sử dụng bên trong Actionnơi chúng được tạo và không được chia sẻ giữa các hành động khác nhau hoặc các hoạt động khác nhau của cùng một hành động, để các hành động có tính quyết định và có thể lặp lại.
Chúng ta có thể sử dụng các loại được xếp hạng cao hơn để thực hiện điều này bằng cách thêm một tham số Scho Resourcevà Actioncác loại, đó là hoàn toàn trừu tượng, nó đại diện cho phạm vi của phạm vi Action. Bây giờ chữ ký của chúng tôi là:
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)
Bây giờ khi chúng tôi đưa ra runActionmột Action<S, T>, chúng tôi chắc chắn rằng vì tham số phạm vi phạm vi của chế độ Sđa hình, nó không thể thoát khỏi cơ thể của runActionbất kỳ giá trị nào của một loại sử dụng Snhư Resource<S, int>vậy cũng không thể thoát!
(Trong Haskell, đây được gọi là STđơn nguyên, nơi runActionđược gọi runST, Resourceđược gọi STRefvà newResourceđược gọi newSTRef.)
let sdff = (g : (f : <T> (e : T) => void) => void) => {}