2014-10-17 3 views
1

저는 하스켈을 배우는 동안 즐겁게 지내 왔으며 여기와 #haskell에서 도움을 받아 좋은 발전을 이루고 있다고 생각합니다. 내 학습은 대부분 예제를보고 거기에 적용된 기법을 추상화하여 내 코드에 적용하려고 할 때가 대부분입니다.모나드 스택에서 persistent를 사용하는 방법은 무엇입니까?

현재 다양한 응용 프로그램 용 모나드 스택을 개발하기 시작했습니다. 영구 응용 프로그램의 기능을 응용 프로그램에 통합하려고합니다.

newtype App a = App { unApp :: StateT AppState (SqlPersistT (ResourceT (LoggingT IO))) a } 
       deriving (Applicative 
         , Functor 
         , Monad 
         , MonadIO 
         , MonadState AppState 
         ) 

AppState이 예에서 하나의 int 값을 유지 단지 기록 데이터 형식입니다 :

여기 내 모나드 스택이다. runApp이 예상되는

main = runApp "./test.sqlite" (AppState 69) runMigrate 

모든 모나드를 푸는 :

내 주요 기능은 같다

runApp :: Text -> AppState -> App a -> IO a 
runApp t s a = 
    runStdoutLoggingT . runResourceT . withSqliteConn t . runSqlConn . flip evalStateT s . unApp 

runMigrateApp 모나드에서 실행할 수있는 응용 프로그램입니다.

Main.lhs:59:16: 
    Couldn't match type ‘m0()’ with ‘()’ 
    Expected type: App() 
     Actual type: App (m0()) 
    In the expression: return $ liftPersist $ runMigration migrateAll 
    In an equation for ‘runMigrate’: 
     runMigrate = return $ liftPersist $ runMigration migrateAll 

질문 :

runMigrate :: App() 
runMigrate = return $ liftPersist $ runMigration migrateAll 

컴파일러는 내가 불만과 함께 일을하고 무엇을 모르는 지적이 경우 난 그냥 마이그레이션을 실행하는 얻기를 위해 촬영 된

  1. 어떻게해야할까요?

  2. 내 모나드 스택에서 ReaderT을 도입하면 어떻게됩니까? SqlPersistT이 실제로 ReaderT 인 것을 감안할 때 ask이 이 아닌 SqlPersistT과 일치하는지 어떻게 확인할 수 있습니까? 첫 번째 질문에 대한

답변

1

: returnreturn의 포인트는 return x이 모나드의 일을 전혀하지 않고, 단지 값을 반환한다는 것입니다 --- 올바른 함수가 아닙니다. 나는 당신이 아마 원하는 생각 :

runMigrate = App $ lift $ runMigration migrateAll 

App는 모나드로 newtype 정의를 리프트; liftPersistT을 포장 StateT으로 들어 올립니다.

(당신이 그것을 많이 사용하는 거라면 덧붙여, 나는 runMigrationApp 같은으로 App . lift . runMigration 이름을 지정하는 것이 좋습니다.)