2016-08-27 5 views
-4

내 코드는 다음과 같습니다.왜 형식 불일치 오류가 발생합니까?

StateParser.hs:43:29 
    Couldn't match type `m' with `State s1' 
     `m' is a rigid type variable bound by 
      the type signature for result_sm :: Functor m => a -> StateM m s a 
      at StateParser.hs:42:14 
    Expected type: m (a, s) 
     Actual type: State s1 (a, s) 
    ... 
    In the expression: result_s (v, s) 
    In the first argument of `StateM', namely 
     `(\ s -> result_s (v, s))' 

StateParser.hs:46:33: 
    Couldn't match type `m' with `StateM m0 s0' 
     `m' is a rigid type variable bound by 
      the type signature for 
      bind_sm :: Functor m => 
         StateM m s a -> (a -> StateM m s b) -> StateM m s b 
      at StateParser.hs:45:12 
    Expected type: StateM m0 s0 (m (b, s)) 
     Actual type: m (m (b, s)) 
    ... 
    In the first argument of `bind_sm', namely `tmp s' 
    In the expression: (tmp s `bind_sm` id) 

그들을 일치시킬 수 있어야 타입 생성자 State sStateM f s에 대한 Functor typeclass의 그러나, 나는 매우 명확하게 정의한 경우, : 컴파일 할 때

{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE FlexibleInstances #-} 

module StateParser where 
import Control.Monad 
import Control.Applicative 

newtype State s a = State {compute :: s -> (a, s)} 

newtype StateM m s a = StateM {compute_M :: s -> m (a, s)} 

result_s :: a -> State s a 
result_s v = State (\s -> (v ,s)) 

bind_s :: State s a -> (a -> State s b) -> State s b 
bind_s st f = State $ \s -> (\(v, s') -> compute (f v) s') (compute st s) 

result_sm :: (Functor m) => a -> StateM m s a 
result_sm v = StateM (\s -> result_s (v, s)) 

bind_sm :: (Functor m) => StateM m s a -> (a -> StateM m s b) -> StateM m s b 
bind_sm stm f = StateM $ \s -> (tmp s `bind_sm` id) 
    where 
    tmp s = fmap (\(v, s') -> compute_M (f v) s') (compute_M stm s) 

instance Functor (State s) where 
    fmap f st = st >>= (pure . f) 

instance Applicative (State s) where 
    pure = result_s 
    p <*> q = p >>= \f -> 
      q >>= (pure . f) 

instance Monad (State s) where 
    --Explicit return definition only required for code required to be compatible 
    --with GHC versions prior to 7.10. The default implementation for all GHC 
    --versions from 7.10 is 
    return = pure 
    (>>=) = bind_s 

instance Functor f => Functor (StateM f s) where 
    fmap f stm = stm `bind_sm` (result_sm . f) 

instance Applicative f => Applicative (StateM f s) where 
    pure = result_sm 
    p <*> q = p `bind_sm` \f -> 
      q `bind_sm` (pure . f) 

instance Monad m => Monad (StateM m s) where 
    return = pure 
    (>>=) = bind_sm 

, 나는 2 유형 불일치 오류를 얻을 변수 유형이 m이고 Functor typeclass가 bind_smresult_sm에 바인딩되어 있습니다.

아마 내가 모르고있는 하스켈의 유형 추론 절차의 일부 측면이있을 수 있습니다. 누군가가 나를 계몽 할 것인가?

+0

여기에서 마술은 일어나지 않습니다. 기능이 잘못되었으므로 (유형이 정확하지 않습니다), 유형 검사기가이를 거부 할 수 있습니다. 컴파일러가 프로그램이 틀린 이유를 정확하게 알려 주었기 때문에 잘못되었다는 것을 고쳐 봤습니까? (오류를 읽었습니까?) 적어도 StateM $ \ s -> .. \'bind_sm \'..'는'StateM'이's -> StateM m0 x0 (StateM m1 x1 a, s))'그것은 분명히하지 않습니다. – user2407038

답변

4
result_sm v = StateM (\s -> result_s (v, s)) 

나에게 잘못되었습니다. StateM는 임의 m위한

s -> m (a,s) 

아니라 m ~ State s 기대하면서 기능

\s -> result_s (v, s) 

s -> State s (a,s) 

입력 갖는다.

result_sm :: (Monad m) => a -> StateM m s a 
result_sm v = StateM (\s -> return (v, s)) 

(또는 실용적 변형) :

당신은 당신이 뭔가를하지 않으시겠습니까?

+2

위의 코드 또는 사용자와 관련된 오류입니까? 후자는 형식 서명을 변경해야했기 때문에 이해할 수 있습니다. – chi

+2

@UnchartedWaters, 당신은 자신의 목적에 큰 도움이되지 못합니다. @chi 코드는 다음과 같이'result_sm'을 사용하여 문제를 해결했다는 것을 보여주었습니다 : http://lpaste.net/180892'bind_sm'과 다른 영역에 다른 문제가 있지만, 이것은 첫 번째 오류에 대한 해결책입니다. – ErikR

관련 문제