2011-02-06 6 views
4

누군가가 모나드 내부에서 스냅 모나드를 사용하는 방법을 보여줄 수 있습니까? 모나드 변압기가 나를 혼란스럽게합니다. (또는 모나드 변압기에 대한 자습서 제안과 조명을보고 최종적으로 불을 붙이는 방법을 기꺼이 받아 들일 것입니다.)리더 모나드를 스냅으로 사용 (또는 모나드 트랜스포머를 스냅으로 사용)

편집 : 죄송합니다. 특정 일에 대한 도움을 요청하는 대신 실제로 내가하려고하는 것을 지정하는 것을 잊어 버렸습니다. 전술이 아닌 전략. 나는 명시 적으로 경로를 지정할 때 해당 데이터베이스 연결/풀을 전달할 필요없이 모든 핸들러간에 데이터베이스 연결/풀을 공유하려고합니다. 독자 모나드가 그것을 성취 할 수있는 방법 일 것 같습니다.

답변

5

스냅는 당신이 필요로하는 어떤 응용 프로그램 전체 자원 (DB 연결, 템플릿 엔진 등)

그것은 생성 된 파일 Application.hs에 위치하고 있으며 기본적으로는 HeistState 및 TimerState이 ApplicationState에 포함이 패키지 수 ApplicationState 유형이 . db 연결을 거기에 넣으면 Snap 애플리케이션의 어느 곳에서나 사용할 수 있습니다.

+0

이것은 내가 사용했던 스냅의 마지막 버전 (0.2.x 무언가였습니다. 내가 아는 한) 이후로 새로워 야합니다. 그러나 그것은 제가 원했던 것입니다. 감사. – tehgeekmeister

0

스냅 모나드가 http://hackage.haskell.org/packages/archive/snap-core/0.4.0/doc/html/Snap-Types.html 인 것으로 가정합니다. 스냅은 모나드 변압기가 아니므로 임의의 모나드 내부에서 실행할 수 없습니다. ReaderT 트랜스포머를 사용하여 Snap 기능에 Reader 기능을 내장 할 수 있습니다.

runSnap의 유형은 그것이 Iteratee ByteString IO 모나드에서 실행되는 것을 우리에게 알려줍니다

runSnap :: Snap a -> (ByteString -> IO()) -> (Int -> IO()) -> Request -> Iteratee ByteString IO (Request, Response) 

입니다. 독자 모나드는 입출력을하거나 입력 스트림을 반복 할 수 없으므로 리더 모나드에서 스냅 계산을 실행할 수 없습니다.

달성하려는 것을 설명하면 누군가가 그것을 달성 할 수있는 방법을 제안 할 수 있습니다. 당신이 GHC 특정 확장자를 사용하는 것을 두려워하지 않은 경우

+0

정말 대단한 것을 반영하여 업데이트되었습니다. 죄송합니다. – tehgeekmeister

4

, 여기 모나드 변압기에 노 하지요 접근이다 :

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

import Control.Monad.Reader 

data ReaderData = ... 

newtype MyMonad a = MyMonad (ReaderT ReaderData Snap a) 
    deriving (Monad, MonadReader ReaderData) 

runMyMonad :: MyMonad a -> ReaderData -> Snap a 
runMyMonad (MyMonad m) r = runReaderT m r 

liftSnap :: Snap a -> MyMonad a 
liftSnap act = MyMonad (lift act) 

이제 독자의 데이터에 액세스 할 수 asklocal를 사용할 수 있습니다. Snap 모나드에서 동작을 실행하려면 새 모나드로 "리프트"해야합니다.

... r <- liftSnap $ ... snap action ... 

더 짧은 이름을 선호 할 수도 있습니다. 그럼, 단지 snap 일 수도 있습니다.

+0

당신은'newtype'을 필요로하지 않습니다, 그것은 단지 타입 동의어가 될 수 있습니다 :'type MyMonad = ReaderT ReaderData Snap'. 그런 다음 표준'lift :: Snap a -> MyMonad a'를 사용하십시오. – luqui

+0

ReaderData는 독자가 원하는 모든 유형의 리더 데이터입니다. – tehgeekmeister

+1

@tehgeekmeister : 예. @luqui : newtype을 사용하지 않은 경험은 대개 길 아래의 문제로 이어집니다. – nominolo