2017-04-06 8 views
2

저는 하스켈 모나드를 가지고 놀고 있습니다. 나는 수정할 수없는 오류가 계속 발생합니다. 내 코드 세그먼트는 상태 Monad를 사용하여 문자열의 처음 두 문자를 함께 추가하고이를 상태의 일부로 반환합니다. 내 "풋"라인은 계속 오류를 표시합니다.계속하시오 (FlexibleContexts를 사용하여 이것을 허용하십시오) 간단한 Haskell 함수에서 에러가 발생했습니다.

* Non type-variable argument in the constraint: MonadState [a] m 
    (Use FlexibleContexts to permit this) 
* When checking the inferred type 
    testH :: forall (m :: * -> *) a. MonadState [a] m => [a] -> m [a] 

어떻게 해결할 수 있습니까? 언어를 확장하는 것은 난 그냥 알 수 있듯이 당신은 하나가 FlexibleContexts을 가능하게함으로써이 문제를 해결 할 수는

test xs = 
runState (testH (tail xs)) ((head xs):[]) 

testH xs = 
do 
    a <- get 
    put ((head xs):a) 
    b <- get 
    return b 
+0

'Control.Monad.State'을 (를) 가져 오는 중입니까? 그렇다면 대신'Control.Monad.Trans.State'를 가져와보십시오. – Alec

+1

"언어 확장은 선택 사항이 아닙니다."라는 것이 무엇인지 알 수 있을지 잘 모르겠습니다. 모나드로 그냥 놀고 있다면'{- # LANGUAGE FlexibleContexts # -}'를 코드 상단에 추가하면 어떨까요? – Lazersmoke

+0

"언어 확장은 옵션이 아닙니다."단, 범위에'MonadState'가있는 것만으로'MultiParamTypeClasses'를 사용하고 있기 때문에 이미 언어를 확장했습니다. –

답변

0

을 일을 내가 얻을하려면 코드를 변경하는 방법을 알 필요하거나 기능을 변경하여 작업, 선택 사항이 아닙니다 목록보다 더 일반적인 것.

하스켈은 컨텍스트 내에서 타입이 아닌 변수를 허용하지 않습니다. 당신이 (당신이 어쨌든 일을해야한다)하여 기능의 유형을 작성하는 경우, 당신은 값 목록을 취하고있는 능력을 가지고 몇 가지 모나드에서 작업을 반환하는 함수 의미

testH :: (Monad m,MonadState [a] m) => [a] -> m [a] 

를 얻을 수 입력과 동일한 유형의 값 목록 상태를 유지합니다. 불행히도 컨텍스트 내의 [a] 비트는 타입이 아닌 변수가있는 (즉,리스트 타입 생성자) Haskell이 유효하지 않습니다.

여기서 가장 좋은 해결책은 유형이 아닌 변수를 허용하는 확장을 허용하는 것입니다. 위험하지 않아 그냥 표준을 완화합니다. 사실, 다중 매개 변수 typeclasses (예 : MonadState)는 유효하지 않으므로 이미 선호하는 언어 확장을 사용하고 있습니다.

실제로 이것이 옵션이 아니면 (Monad m,SomeTypeclass f,MonadState (f a) m)으로 변경하고 선택한 SomeTypeclass 다음에 오는 생성자에서 작동하도록 함수를 다시 작성할 수 있습니다. 이렇게하면 형식에서 목록 형식 생성자가 제거되고 FlexibleContexts없이 코드가 작동합니다.