実行を「表示」するためのモノイドを含むアプリケーションファンクターに取り組んでいます。ただし、この部分がまったく気にならない場合もあるため、モノイドの選択は、決して消費されないため意味がありません。私が持っているものを単純化しました:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
import GHC.Exts
class Render a b where render :: a -> b
instance Render a () where render = const ()
class Merge a where
type Renderer a b :: Constraint
merge :: Renderer a b => a -> b
data Foo = Foo Bool
instance Merge Foo where
type (Renderer Foo) m = (Render Bool m)
merge (Foo b) = render b
Render
a
さまざまなを単一のに変換するために使用されb
ます。Merge
私の実際のファンクターを大幅に単純化したものですが、要点は、型ファミリー/制約が含まれていることであり、その意図はRender
、Merge
必要なものを正確に指定することです。
ここで、 を「実行」したいかもしれませんが、Merge
次のようなビューを破棄します。
runFoo :: Merge a => a -> Int
runFoo x = case merge x of () -> 5
しかし、これは次の理由で失敗します。
(Renderer a ())
の使用から生じると推測できませんでしたmerge
()
foralla
のインスタンスがあるため、モノイドとして選択しましたRender a ()
。したがって、それがMerge a
単にコレクションのRender
制約を意味すると言う方法があれば、これはうまく機能します。もちろん、Merge a
それよりも一般的です-コンパイルエラーを説明する任意の制約を追加できます。
の署名を変更せずに、私が望むものを達成する方法はありrunFoo
ますか?