2015-08-31 3 views
4

Так что я этот рабочий пример (Snap + Postgres):плавные типа аннотаций в цепи связывания

listBooks :: AppHandler() 
listBooks = do 
    results <- query_ "select * from books" 
    writeJSON $ (results :: [Book]) 

В качестве упражнения я пытаюсь переписать с >>= оператором, но необходимость аннотирования типа убивает эстетика. Я не мог придумать ничего лучшего:

query_ "select * from books" >>= return.(\x -> x :: [Book]) >>= writeJSON 

Есть ли какой-нибудь другой «более гладкий» способ? (Желательно без указания типа оберточной монады)

+2

Вам нужно указать тип либо с помощью встроенной аннотации, либо с подписями в отдельном определении. Кстати, есть [запланированное расширение GHC] (https://ghc.haskell.org/trac/ghc/ticket/10803), которое обеспечит синтаксический сахар для вашего второго фрагмента. – duplode

ответ

7

Вы можете сократить его немного

query_ "select * from books" >>= writeJSON . (\x -> x :: [Book]) 

кроме этого, еще нет, хотя есть планы по реализации расширения GHC для быстрого синтаксиса

(:: [Book]) = (\x -> x :: [Book]) 

Глядя на @duplode's link , похоже, что код для этого начал писать 3 дня назад, поэтому должен быть в следующем выпуске GHC.

5

Если включить PartialTypeSignatures, вы можете написать:

query_ "select * from books" >>= (writeJSON :: [Book] -> _) 

Можно было бы также означать это как ограничение на query_; например в вашей версии do, было бы:

listBooks :: AppHandler() 
listBooks = do 
    results <- query_ "select * from books" :: _ [Book] 
    writeJSON results 

В будущих версиях GHC, также будет видно приложение типа. Если предположить, что writeJSON или query_ имеет соответствующее объявление типа, вы бы тогда быть в состоянии написать один из них:

query_ @[Book] "select * from books" >>= writeJSON 
query_ "select * from books" >>= writeJSON @[Book] 

Наконец, если вы не склонны к типу аннотаций, но хорошо с термином аннотацией, вы могли бы написать

query_ "select * from books" >>= asAppliedTo [Book{}] writeJSON 

где Book - гипотетический конструктор для типа Book (точка [Book{}], в то время как бессмысленное значение имеет мономорфный тип). Я, кажется, помню, что asAppliedTo - это стандартная вещь, но быстрый hoogle не раскрывает ее; в любом случае он реализуется аналогично этому:

asAppliedTo :: arg -> (arg -> result) -> (arg -> result) 
asAppliedTo _ = id 
+0

Для «стандартной вещи» существует ['asTypeOf :: a -> a -> a; asTypeOf = const'] (http://hackage.haskell.org/package/base-4.8.1.0/docs/Prelude.html#v:asTypeOf). – duplode

Смежные вопросы