프리 모나드에 상태 모나드를 삽입 할 수 있습니다. 하나가 일치하지 않으면 왜 '겹치는 인스턴스'오류가 발생합니까?
{-# language FlexibleInstances, MultiParamTypeClasses #-}
module Main where
import Control.Monad.Free
import Control.Monad.State
import Data.Bifunctor
data Toy state next =
Output String next
| LiftState (state -> (next, state))
| Done
instance Functor (Toy s) where
fmap f (Output str next) = Output str $ f next
fmap f (LiftState stateF) = LiftState (first f . stateF)
fmap f Done = Done
instance MonadState s (Free (Toy s)) where
state = overState
overState :: (s -> (a, s)) -> Free (Toy s) a
overState = liftF . LiftState
output :: Show a => a -> Free (Toy s)()
output x = liftF $ Output (show x)()
done :: Free (Toy s) r
done = liftF Done
program :: Free (Toy Int)()
program = do
start <- get
output start
modify ((+10) :: (Int -> Int))
end <- get
output end
done
interpret :: (Show r) => Free (Toy s) r -> s -> IO()
interpret (Free (LiftState stateF)) s = let (next, newS) = stateF s
in interpret next newS
interpret (Free (Output str next)) s = print str >> interpret next s
interpret (Free Done) s = return()
interpret (Pure x) s = print x
main :: IO()
main = interpret program (5 :: Int)
내가 오류 얻을 : 여기 내 간단한 시도의 지금까지 내가 수집 할 수
• Overlapping instances for MonadState Int (Free (Toy Int))
arising from a use of ‘get’
Matching instances:
instance [safe] (Functor m, MonadState s m) =>
MonadState s (Free m)
-- Defined in ‘Control.Monad.Free’
instance MonadState s (Free (Toy s))
-- Defined at app/Main.hs:18:10
• In a stmt of a 'do' block: start <- get
In the expression:
do { start <- get;
output start;
modify ((+ 10) :: Int -> Int);
end <- get;
.... }
In an equation for ‘program’:
program
= do { start <- get;
output start;
modify ((+ 10) :: Int -> Int);
.... }
는; 이 경우 적용하려고 다음 free package here에서
(Functor m, MonadState s m) => MonadState s (Free m)
을; 그러나이 경우에는 Free (Toy s)
과 일치해야하고 필요에 따라 MonadState s (Toy s)
이 없으므로 적용되는 이유를 이해할 수 없습니다. 내 인스턴스 정의를 제거하면
내가 얻을 :
다른 인스턴스가 실제로 적용되지 않습니다 내 생각을 지원• No instance for (MonadState Int (Toy Int))
arising from a use of ‘modify’
; 어떻게하면 지정된 인스턴스를 사용하여 이것을 컴파일 할 수 있습니까? 왜 이것이 발생하는지 설명 할 수 있습니까? FlexibleInstances
이 사용 되었기 때문입니까?
감사합니다.
메타 주석 :이 질문은 모두 무언가의 복제본이어야합니까? –