Không, bạn không thể. Vấn đề cơ bản là cú pháp của Haskell đã lừa bạn nghĩ rằng các kiểu của f1
và f2
tương tự hơn so với thực tế. Khi dịch sang GHC Core, họ trông khá khác nhau nhiều:
f1 :: forall a . a -> [a]
f2 :: Int -> Int
Không chỉ này, nhưng tương ứng về cái nhìn khá khác nhau:
f1 = Λa -> λ(x :: a) -> [x]
f2 = λ(x :: Int) -> 3 * x
Như bạn thấy, f1
và f2
thực sự có số đối số khác nhau, trong đó f1
mất một loại và một giá trị và f2
chỉ mất một giá trị.
Trong nhiều hoàn cảnh bình thường, khi bạn tiếng tom f2
vào một bối cảnh chờ đợi một chức năng của loại, chẳng hạn, Int -> [Int]
, GHC sẽ áp dụng f2
với loại cần thiết cho bạn (ví dụ, nhanh chóng f2
đến một loại hình cụ thể), và tất cả ý chí mạnh giỏi nhé. Ví dụ, nếu bạn có
g :: (Int -> [Int]) -> Bool
và bạn áp dụng g
-f
, GHC sẽ thực sự biên dịch đó để
g (f @Int)
Nhưng ở đây bạn muốn đa hình về việc liệu instantiation điều đó xảy ra hay không, mà GHC doesn' t hỗ trợ (Tôi nghĩ rằng nó sẽ là một thay đổi khá triệt để và phá hoại đối với ngôn ngữ cốt lõi).
Vì trường hợp lớp, nhập mẫu gia đình và nhập kết quả gia đình không thể được định lượng, tôi khá tự tin không có cách nào để có được thứ bạn muốn.
như @ErikR cho thấy bạn trong câu trả lời (bị xóa) phía bên tay trái của bạn có thể thực hiện được nhưng loại trên rhs phụ thuộc vào loại 'f' vì vậy tôi đoán bạn sẽ cần sử dụng kiểu-gia đình - nếu điều này phù hợp với bạn hơn là có thể - tất nhiên đây chỉ là phỏng đoán - cho tất cả tôi biết có cách để diễn đạt điều này;) – Carsten
Vui lòng sử dụng tiện ích mở rộng GHC – Clinton
@ user3237465: trong nháy mắt (ít nhất là phiên bản đơn giản của bạn) Tôi nghĩ rằng bạn sẽ gặp rắc rối với 'f2' vì đây không phải là * forall a * nhưng chỉ cho' Int' còn – Carsten