これは、ハンドラーを次のように見せようとしているものです-
getUserStudentsR :: UserId -> Handler TypedContent
getUserStudentsR userId =
getStudentEntitiesForCoach userId
>>= returnTypedContent . map toUserStudentResponse
ここで、Student は永続エンティティ (詳細はほとんど重要ではありません) であり、
getStudentEntitiesForCoach :: UserId -> HandlerT App IO [Entity Student]
getStudentEntitiesForCoach coachId =
runDB $ selectList [StudentPrimaryCoachId ==. Just(coachId)] []
data UserStudentResponse = StudentResponse (Key Student) Student
instance ToJSON UserStudentResponse where
toJSON (StudentResponse studentId student) =
object
[
"login" .= studentLogin student
, "studentId" .= studentId
, "firstName" .= studentFirstname student
, "lastName" .= studentLastname student
]
toUserStudentResponse :: (Entity Student) -> UserStudentResponse
toUserStudentResponse (Entity studentId student)
= StudentResponse studentId student
と
returnTypedContent x = selectRep $ do
provideJson x
明らかに、UserStudentResponse が ToJSON をインスタンス化し、toJSON の実装を提供しない限り、これはコンパイルされません。ただし、 returnTypedContent 関数をジェネリックにしたい-次のような-
returnTypedContent x = selectRep $ do
-- if ToJSON x --
provideJSON x
-- if ToHTML x -- -- note this is not an either or
provideRep $ return $ toHtml $ a
returnTypedContent を拡張してすべての種類のコンテンツ タイプの戻り値を提供できるようにしたいので、ハンドラーで使用されるデータ型が特定の型クラス (ToJSON など) をインスタンス化するかどうかに基づいて、さまざまなものが提供されます。
Template Haskellに行かなくても、このようなことは可能ですか?