從來沒有擺弄這個東西,但這裏可能有兩個部分的答案可能足夠你。恐怕這不是一個通用的解決方案,也不是一種製作Dynamic
和Eq
實例的方法(如果它很簡單,它可能已經是一個了)。
但是在你上次的評論中,你表示你只是想比較自己的類型。所以,部分回答1:
如果你猜他們的類型,你當然可以比較兩個Dynamics
。例如:
eqInt :: Int -> Int -> Bool
eqInt = (==)
x = toDyn (3::Int)
y = toDyn (3::Int)
z = toDyn (4::Int)
compareDynamic :: (Typeable a, Eq a) =>
(a -> a -> Bool) ->
Dynamic -> Dynamic -> Maybe Bool
compareDynamic eq x y = do
let dEq = toDyn eq
fn1 <- dynApply dEq x
res <- dynApply fn1 y
fromDynamic res
現在:
...> compareDynamic eqInt x y
Just True
...> compareDynamic eqInt x z
Just False
然而,儘管有誤導性的多態型的compareDynamic
,你只能傳遞一個單態比較功能。請參閱:
...> compareDynamic (==) x z
Nothing
我想這是因爲該類型系統無法知道其中的(==)
比如,它實際上應該在這裏使用的方式。我保持compareDynamic
多態,但不必爲每種類型創建單獨的函數。
現在,因爲你只需要比較自己的類型,你可以只是比較功能的列表,你才能嘗試:
eqs = [eqMyTypeA, eqMyTypeB, eqMyTypeC]
comp dynA dynB = catMaybes $ map (\eq -> eq dynA dynB) eqs
而且[]
將意味着兩種不同類型,[Just False]
同一類型具有不同的值和[Just True]
相同的類型和價值。
如果您有大量類型,您也可以在做比較之前確定構造函數(這是部分答案2),並根據它選擇正確的函數。它的構造函數是不同的,你根本不需要進行比較:
constructor :: Dynamic -> TyCon
constructor = typeRepTyCon . dynTypeRep
並且有一個匹配構造函數和相等函數的查找表。
一個結束語:如果你需要這個,請三思。想想三次,如果你需要Dynamic
,大多數Haskell程序都不需要。是不是隻有Java思維偷偷摸摸?
我認爲爲Dynamic創建一個'Eq'實例是不可能的。爲了比較兩個對象,如果你知道類型,你就完成了,如果沒有,就會遇到麻煩 - 你不能將值轉換回靜態世界,因爲你不知道要強制的類型,除非你賦予它一個單形類型(以及你可以如何創建一個動態的相等謂詞?),否則你不能創建'(==)''Dynamic'。 (請參閱[API](http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Dynamic.html)。)除非這是一個實驗,否則可能有更好的方法來完成無論你想要做什麼。 – Fixnum
你知道如何從靜態類型導出動態的Eq行爲嗎? – ye9ane
我認爲'Data.Dynamic'的作者沒有提供這樣一個實例,這是你不能寫的:)的一個很好的理由。 – Fixnum