Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 在服务中的API端点内发出请求_Haskell_Servant - Fatal编程技术网

Haskell 在服务中的API端点内发出请求

Haskell 在服务中的API端点内发出请求,haskell,servant,Haskell,Servant,我正试图用它来建立一个电报机器人。到目前为止,我还没有遇到过这样的问题,因为我可以阅读测试来了解事情是如何工作的,但是当涉及到使用构建webhook端点时,我遇到了很多麻烦。总的想法是,当我从webhook收到更新时,我会发回一个回复 问题在于我的postWebhook代码,它希望接收消息,但却接收IO消息。我认为这是因为Servant不希望我在该函数中发出请求,因为我有类型eitherservanterror IO(IO消息)(部分由BotHandler)而实际上应该是eitherservan

我正试图用它来建立一个电报机器人。到目前为止,我还没有遇到过这样的问题,因为我可以阅读测试来了解事情是如何工作的,但是当涉及到使用构建webhook端点时,我遇到了很多麻烦。总的想法是,当我从webhook收到
更新时,我会发回一个回复

问题在于我的
postWebhook
代码,它希望接收
消息
,但却接收
IO消息
。我认为这是因为Servant不希望我在该函数中发出请求,因为我有类型
eitherservanterror IO(IO消息)
(部分由
BotHandler
)而实际上应该是
eitherservanterror IO消息

我还在学习Haskell,但我明白我必须以某种方式从IO monad中获得信息?更新
BotAPI
以返回
Post'[JSON](IO消息)
给了我这样一个信息:
使用“serve'
不会产生(可折叠IO)的实例,这超出了我的初学者知识,我可以看到,摆弄类型只会将相同的问题转移到代码的不同部分。我只是不知道如何解决这个问题

以下是删除敏感字符串的代码:

{-# LANGUAGE DataKinds         #-}
{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators     #-}

module Main where

import           Control.Monad
import           Control.Monad.Trans.Either
import           Data.Proxy
import           Data.Text                  (Text, pack)
import           Network.Wai.Handler.Warp
import           Servant
import           Web.Telegram.API.Bot

reply :: Token -> Message -> Text -> IO Message
reply token msg response = do
  Right MessageResponse { message_result = m } <-
    sendMessage token $ SendMessageRequest chatId response (Just Markdown) Nothing Nothing Nothing
  return m
  where chatId = pack . show $ chat_id (chat msg)

type BotAPI = "webhook" :> ReqBody '[JSON] Update :> Post '[JSON] Message
type BotHandler a = EitherT ServantErr IO a

botApi :: Proxy BotAPI
botApi = Proxy

initWebhook :: Token -> IO Bool
initWebhook token = do
  Right SetWebhookResponse { webhook_result = w } <-
    setWebhook token $ Just "https://example.com/webhook"
  return w

postWebhook :: Token -> Update -> BotHandler (IO Message)
postWebhook token update = case message update of
  Just msg -> return $ reply token msg "Testing!"
  Nothing -> left err400

server :: Token -> Server BotAPI
server = postWebhook

main :: IO ()
main = do
  initWebhook token
  run port $ serve botApi (server token)
  where token = Token "<token>"
        port = 8080
{-#语言数据类型}
{-#语言派生类{-}
{-#语言重载字符串}
{-#语言类型运算符{-}
模块主要在哪里
进口管制
进口控制。单子。反式
导入数据。代理
导入数据.Text(文本,包)
导入Network.Wai.Handler.Warp
进口佣人
导入Web.telegrame.API.Bot
回复::令牌->消息->文本->IO消息
回复令牌msg response=do
右MessageResponse{message_result=m}ReqBody'[JSON]Update:>Post'[JSON]message
类型BotHandler a=EitherT ServantErr IO a
botApi::代理botApi
botApi=代理
initWebhook::令牌->IO布尔
initWebhook令牌=do
右SetWebhookResponse{webhook_result=w}更新->BotHandler(IO消息)
postWebhook令牌更新=案例消息更新
只需msg->return$reply token msg“Testing!”
没什么->剩下400
服务器::令牌->服务器BotAPI
服务器=postWebhook
main::IO()
main=do
initWebhook令牌
运行端口$serve botApi(服务器令牌)
其中token=token“”
端口=8080
为可能不理想的Haskell代码道歉。提前感谢:)

您的错误在

Just msg → return $ reply token msg "Testing!"
你上了

EitherT ServantErr IO Message
monad但是回复有类型

reply :: Token → Message → Text → IO Message
然后简单地将
IO
动作提升到monad中,它就可以工作了

postWebhook :: Token → Update → BotHandler Message
postWebhook token update = case message update of
  Just msg → lift $ reply token msg "Testing!"
  Nothing  → left err400

(解释这里涉及的所有事情并不容易)我认为你应该多练习单子、变形金刚。。。在这些复杂的例子面前,但你很勇敢!:)

哇,有人在用它!