pipes
ライブラリのタイプクラスを作成して、Proxy
のようなタイプの抽象インターフェースを定義しています。型クラスのようなものになります。タイプクラスまたはインスタンスの派生変数を制限する
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.のような醜いハックでしかできません。 Edward Kmettはhttp://hackage.haskell.org/packages/archive/constraints/0.3.2/doc/html/Data-Constraint-Forall.htmlにあります。 –