ひどいタイトルに申し訳ありません。私はタイプをラップするMonad
のApplicative
のインスタンスを作成しようとしています。(Monad m、Monoid o)=> m o?
instance (Monad m, Monoid o) => Applicative (m o) where
pure x = return mempty
xm <*> ym = do
x <- xm
y <- ym
return $ x `mappend` y
これは機能しません。 GCHiは文句を言う:
Kind mis-match
The first argument of `Applicative' should have kind `* -> *',
but `m o' has kind `*'
In the instance declaration for `Applicative (m o)'
私が上に書いたことは意味をなさないかもしれないことを理解する。コンテキストは次のとおりです。私は、compos
という抽象化を、A pattern for almost compositional functionsの論文に記載されているように使用しようとしています。このツリー撮影(compos
のGADTのバージョンを使用して、私はそれをたくさん簡略化されました):
data Tree :: * -> * where
Var :: String -> Expr
Abs :: [String] -> Expr -> Expr
App :: Expr -> [Expr] -> Expr
class Compos t where
compos :: Applicative f => (forall a. t a -> f (t a)) -> t c -> f (t c)
instance Compos Tree where
compos f t =
case t of
Abs ps e -> pure Abs <*> pure ps <*> f e
App e es -> pure App <*> f e <*> traverse f es
_ -> pure t
私は木を下降機能の多くを書くと言うエラーやのリストを返すつもりですなど、それは(そのような結合環境など)ダウンしたとしても、状態を必要としながら、文字列の集合、:
composFoldM :: (Compos t, Monad m, Monoid o) => (forall a. t a -> m o) -> t c -> m o
composFoldM f = ???
checkNames :: (Tree a) -> State (Set Name) [Error]
checkNames e =
case e of
Var n -> do
env <- get
-- check that n is in the current environment
return $ if Set.member n env then [] else [NameError n]
Abs ps e' -> do
env <- get
-- add the abstractions to the current environment
put $ insertManySet ps env
checkNames e'
_ -> composFoldM checkNames e
data Error = NameError Name
insertManySet xs s = Set.union s (Set.fromList xs)
私は、これらはすべて(Monad m, Monoid o) => m o
構造のためcomposFoldM
利用compos
を作ることによって抽象化されることができるべきであると思います。 GADT Applicative
バージョンcompos
を575/576ページのthe paperに掲載しています。私はこの構造のApplicative
インスタンスを作る必要があると思います。どうすればいい?それとも、私は間違った道を完全に下っていますか?
これは私が必要とするもののように見えます!しかし、どうすればそれを実際に使用できますか? 'composFoldM f = getComposeのようなことをしようとしました。 compos(WrapMonadを構成するConst。f) 'しかしこれは動作しません。ファンクタを組み合わせる方法の例/説明はありますか? –
私の神。私は最終的に試行錯誤してそれを仕上げました。私はこれがあなたが学ぶ方法だと思います!正しいことは 'composFoldM f = liftM getConstです。 unwrapMonad。 getCompose。コンポジット(WrapMonadを作成します。 :D –
@CallumRogersそうですね!これはHaskellの素晴らしい点の1つです。型チェッカーは常にあなたを正しい解決策に導きます。 –