0
跟進this,我有以下類型類:自動推斷出多參數例如
class Monoid m => BuilderS m a where
cstr :: String -> a -> m
class SafeCopy a where
putSafe :: a -> m
爲BuilderS
提供了實例:
import qualified Data.Serialize.Builder as B
instance Serialize a => BuilderS B.Builder a where
cstr _ = B.fromByteString . encode
instance BuilderS CustomBuilder Int where
cstr = ...
instance BuilderS CustomBuilder String where
cstr = ...
etc.
我想定義的SafeCopy
情況是這樣的:
data Person = Person { name :: String, age :: Int }
instance SafeCopy Person where
putSafe p = cstr "name" (name p)
但是,在這個特定ic情況下,編譯器無法找到BuilderS m String
的實例。我已經試過幾件事情:
- 將所有原始數據類型來的
putSafe
約束:putSafe :: (BuilderS m Int, BuilderS m String, ...) => a -> m
。這工作,但不可擴展(即,如果我想在未來BuilderS m Vector
約束?) - 添加
m
到SafeCopy
類型參數。 - 使用自定義總和類型:
data SumT m = forall a b. (BuilderS m a, BuilderS m b) => a :+: b
,然後有putSafe :: a -> SumT m
。
不過,我沒有提供足夠的信息給類型系統,所以它可以推遲決定哪個確切的實例BuilderS
供以後使用。我錯過了什麼?
(2)[添加m來輸入參數]有什麼問題? – bennofs 2014-08-28 10:30:37
這兩種情況下的'm'都是獨立的。在第二種情況下,'m'是一個自由參數。所以,你應該手動編寫final類型,'putSafe p = cstr「name」(name p):: CustomBuilder String' – viorior 2014-08-28 10:48:20
你的putSafe類型承諾能夠返回調用者想要的任何類型。顯然這是不可能的。 – augustss 2014-08-28 11:47:33