所以我有这个工作示例(Snap + Postgres):
listBooks :: AppHandler ()
listBooks = do
results <- query_ "select * from books"
writeJSON $ (results :: [Book])
作为练习,我试图用>>=
运算符重写它,但注释类型的需要会破坏美学。我无法想出比:
query_ "select * from books" >>= return.(\x -> x :: [Book]) >>= writeJSON
还有其他更顺畅的&#34;办法? (最好不指定包装单子类型)
答案 0 :(得分:7)
你可以稍微缩短到
query_ "select * from books" >>= writeJSON . (\x -> x :: [Book])
除此之外,还没有,尽管有计划为快捷语法实现GHC扩展
(:: [Book]) = (\x -> x :: [Book])
关注@duplode's link 似乎它的代码开始在3天前写完,所以应该在下一个GHC版本中。
答案 1 :(得分: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