所以我有这个工作示例(Snap + Postgres):
listBooks :: AppHandler ()
listBooks = do
results <- query_ "select * from books"
writeJSON $ (results :: [Book])
Run Code Online (Sandbox Code Playgroud)
作为练习,我试图用>>=操作符重写它,但注释类型的需要杀死了美学.我想不出更好的东西:
query_ "select * from books" >>= return.(\x -> x :: [Book]) >>= writeJSON
Run Code Online (Sandbox Code Playgroud)
还有其他"更顺畅"的方式吗?(最好不指定包装单子类型)
你可以稍微缩短一下
query_ "select * from books" >>= writeJSON . (\x -> x :: [Book])
Run Code Online (Sandbox Code Playgroud)
除此之外,还没有,尽管有计划为快捷语法实现GHC扩展
(:: [Book]) = (\x -> x :: [Book])
Run Code Online (Sandbox Code Playgroud)
看看@ duplode的链接 ,好像它的代码开始写入3天前,所以应该在下一个GHC版本中.
如果你打开PartialTypeSignatures,你可以写:
query_ "select * from books" >>= (writeJSON :: [Book] -> _)
Run Code Online (Sandbox Code Playgroud)
人们也可以将此作为约束query_; 例如,在您的do版本中,它将是:
listBooks :: AppHandler ()
listBooks = do
results <- query_ "select * from books" :: _ [Book]
writeJSON results
Run Code Online (Sandbox Code Playgroud)
在GHC的未来版本中,还将有可见的类型应用程序.假设writeJSON或query_具有合适的类型声明,您就可以编写以下其中一个:
query_ @[Book] "select * from books" >>= writeJSON
query_ "select * from books" >>= writeJSON @[Book]
Run Code Online (Sandbox Code Playgroud)
最后,如果您反对输入注释,但可以使用术语注释,那么您可以编写
query_ "select * from books" >>= asAppliedTo [Book{}] writeJSON
Run Code Online (Sandbox Code Playgroud)
哪个Book是该Book类型的假设构造函数(重点是[Book{}],虽然是无意义的值,但是具有单态类型).我似乎记得这asAppliedTo是一个标准的事情,但快速的hoogle并没有透露它; 无论如何,它的实现类似于:
asAppliedTo :: arg -> (arg -> result) -> (arg -> result)
asAppliedTo _ = id
Run Code Online (Sandbox Code Playgroud)