簡體   English   中英

在Haskell中,有沒有辦法強制強制進行多態調用?

[英]In Haskell, is there some way to forcefully coerce a polymorphic call?

我有一個任何類型的值(或函數)列表。 我有另一個類型的功能列表。 運行時的用戶將從第一個列表中選擇一個,從第二個列表中選擇另一個。 我有一個機制來確保這兩個項是類型兼容的(第一個值或輸出與第二個輸入兼容)。

我需要一些方法來使用值調用函數(或組合函數)。 如果第二個函數具有具體類型,則unsafeCoerce工作正常。 但如果是這樣的形式:

polyFunc :: MyTypeclass a => a -> IO ()
polyFunc x = print . show . typeclassFunc x

然后unsafeCoerce無法工作,因為它無法解析為具體類型。

有沒有辦法做我想做的事情?

這是列表可能的樣子。 但是......我不僅限於此,如果有其他方式來代表這些將解決問題,我想知道。 需要考慮的一個關鍵事項是:列表可以在運行時更改,因此我不知道在編譯時可能涉及的所有可能類型。

data Wrapper = forall a. Wrapper a
firstList :: [Wrapper]
firstList = [Wrapper "blue", Wrapper 5, Wrapper valueOfMyTypeclass]
data OtherWrapper = forall a. Wrapper (a -> IO ())
secondList :: [OtherWrapper]
secondList = [OtherWrapper print, OtherWrapper polyFunc]

注意:至於為什么我要做這么瘋狂的事情:我正在生成代碼並使用提示進行類型檢查。 但這發生在運行時。 問題是提示在實際執行時速度很慢,而高性能對此至關重要。 此外,至少在某些情況下,我不想生成代碼並在運行時通過ghc運行它(盡管我們也做了一些)。 所以......我試圖找到中間的某個地方:動態地將事物連接在一起而不必生成代碼和編譯,但是以編譯速度運行而不是解釋。

編輯 :好的,現在我看到了更多的東西,這是一個非常通用的方法 - 不要直接使用多態函數! 而是使用Dynamic -> IO ()類型的函數! 然后,他們可以直接使用“typecase”式調度來選擇調用哪個單態函數 - 即只需打開TypeRep。 必須發稿直接編碼為你包裝每個多態性功能。 但是,如果它變得足夠麻煩,你可以使用一些模板Haskell自動執行此操作。

本質上,正如Dynamic在靜態類型語言中嵌入動態類型語言一樣,而不是重載Haskell的多態性,現在擴展它以在靜態類型語言中嵌入動態多態。

-

舊答案:更多代碼會有所幫助。 但是,據我所知,這是讀/顯問題。 即你有一個產生多態結果的函數,以及一個帶有多態輸入的函數。 問題是需要選擇中間值是什么,以便它滿足兩個約束。 如果你有一個機制這樣做,那么通常的技巧將起作用,確保你滿足編譯器無法知道答案的那個開放式問題。

我不確定我完全理解你的問題。 但是,由於您具有兼容類型的價值和功能,您可以將它們組合成單個值。 然后編譯器可以證明類型匹配。

{-# LANGUAGE ExistentialQuantification #-}

data Vault = forall a . Vault (a -> IO ()) a

runVault :: Vault -> IO ()
runVault (Vault f x) = f xrun

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM