내 previous question에서 모나드 코드를 알아 내려고 노력했습니다.하스켈 "추론 할 수 없다", "타입 변수가 아닌 인수"
import Control.Monad
import Control.Monad.Error
newtype FSM m = FSM { unFSM :: String -> m (String, FSM m) }
fsm f [] = return []
fsm f (r:rs) = do
(xs, f') <- unFSM f r
liftM (xs:) (fsm f' rs)
지금이 잘 컴파일 : 여기에, 시작하려면 상태 시스템 내가 사용 기능입니다
exclaim :: (Monad m) => FSM m
exclaim = FSM exclaim'
exclaim' xs = return (xs ++ "!", exclaim)
하지만이 때문에 유형 선언하지 않습니다 :
question :: (MonadError String m) => FSM m
question = FSM question'
question' xs
| last xs == '?' = throwError "Already a question"
| otherwise = return (xs ++ "?", question)
오류는 Non type-variable argument
입니다. 이는 이후에 String
을 나타냅니다. 형식 선언을 제거하면 대신 Could not deduce
이 표시됩니다. 나는 FlexibleContext를 활성화하는 것이이 문제를 "고칠 수있다"는 것을 이해하고 있지만 오류를 던지기 위해 할 수있는 간단한 방법이 있습니까? 차라리 모든 종류의 컴파일러 확장을 활성화하지는 않을 것입니다.
전체 코드 here. 당신이 절대적으로 FlexibleContexts
또는 NoMonomorphismRestriction
를 사용하지 않을 경우
'FlexibleContexts'는 아주 해가없는 확장입니다. 그 것을 두려워 할 필요가 없습니다. 형식 서명이 없으면 monomorphism 제한을 사용하지 않으면 컴파일됩니다. –
확장 기능이 필요하지 않은 경우에는 약간 불리한 점이 있습니다. 차라리 코드를 재구성하는 대안적인 접근법을 찾고 싶습니다. 솔루션 1은 FlexibleContext입니다. 다른 제안? – me2
더 많거나 적다면 얻을 수있는 모든 솔루션은 "FlexibleContexts를 켜십시오". " 확장 프로그램을 두려워하지 마라. 그들은 당신을 도울 것이다. 그리고 이것은 신비하지 않습니다. 구체적으로 당신이하고 싶은 것을 정확하게 할 수 있도록하는 것입니다. 아무것도 더, 아무것도 덜. – Carl