绑定链

时间:2015-08-31 22:21:51

标签: haskell

所以我有这个工作示例(Snap + Postgres):

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

作为练习,我试图用>>=运算符重写它,但注释类型的需要会破坏美学。我无法想出比:

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

还有其他更顺畅的&#34;办法? (最好不指定包装单子类型)

2 个答案:

答案 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的未来版本中,还会有可见的类型应用程序。假设writeJSONquery_具有合适的类型声明,那么您可以编写其中一个:

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

最后,如果您不愿意输入注释,但可以使用术语注释,那么您可以编写

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

其中BookBook类型的假设构造函数(点是[Book{}],而无意义值,具有单态类型)。我似乎记得asAppliedTo是一个标准的东西,但快速的hoogle并没有透露它;无论如何,它的实现类似于:

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