我正在爲我的pipes
庫編寫一個類型類來定義類似於Proxy
類型的抽象接口。 Type類看起來類似:約束類型類或實例的派生變量
class ProxyC p where
idT :: (Monad m) => b' -> p a' a b' b m r
(<-<) :: (Monad m)
=> (c' -> p b' b c' c m r)
-> (b' -> p a' a b' b m r)
-> (c' -> p a' a c' c m r)
... -- other methods
我還編寫擴展爲Proxy
類型的形式是:
instance (ProxyC p) => ProxyC (SomeExtension p) where ....
...我想這些情況下,能夠如果m
是Monad
那麼p a' a b' b m
對於所有a'
,a
,b'
和b
是Monad
。
但是,我不知道如何幹淨地編碼,作爲ProxyC
類或實例的約束。我目前所知道的唯一的解決辦法是做這樣的事情在類的方法簽名對其進行編碼:
(<-<) :: (Monad m, Monad (p b' b c' c m), Monad (p a' a b' b m))
=> (c' -> p b' b c' c m r)
-> (b' -> p a' a b' b m r)
-> (c' -> p a' a c' c m r)
...但我希望會有一個更簡單,更優雅的解決方案。
編輯:即使不是最後的解決方案有效,因爲編譯器不推導出(Monad (SomeExtension p a' a b' b m))
意味着(Monad (p a' a b' b m))
爲變量的具體選擇,給出下面的實例,即使:
instance (Monad (p a b m)) => Monad (SomeExtension p a b m) where ...
編輯# 2:
class ProxyC p where
return' :: (Monad m) => r -> p a' a b' b m r
(!>=) :: (Monad m) => ...
:我考慮的只是複製
ProxyC
類中的
Monad
類的方法下一個解決方案
...然後用每個ProxyC
實例對它們進行實例化。由於Monad
方法僅需要在內部用於擴展寫入,並且原始類型仍然具有適合下游用戶的適當的Monad
實例,所以這對我的目的來說似乎沒問題。所有這些只是將Monad
方法暴露給實例編寫器。
AFAIK你只能用醜陋的黑客來做它,比如f.e.愛德華Kmett做在http://hackage.haskell.org/packages/archive/constraints/0.3.2/doc/html/Data-Constraint-Forall.html –