在函数extactValues中,我必须返回WeatherValues

时间:2018-05-10 14:20:42

标签: haskell

我不得不问如何解决这个问题

Couldn't match type ‘Response String’ with ‘[Char]’
      Expected type: String
        Actual type: Response String

和这个

Couldn't match type ‘Response String’ with ‘[Char]’
      Expected type: String
        Actual type: Response String

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}

module PrepareAnswer where

import Data.Text
import Data.Aeson
import Network.HTTP.Client
import GHC.Generics
import Control.Monad
import Data.Maybe
import Data.Aeson.Encode.Pretty
import Data.ByteString
import AskWeather
import Data.Aeson.Types
import Data.ByteString.Char8 

data TempUnits = Celsiuses
               | Farenheits deriving (Generic, Show)

data WeatherValues = WeatherValues
                   { temp_min :: Text
               , temp_max :: Text
               } deriving (Show)

extractValues :: Response String -> WeatherValues
extractValues response =
    let rawJSON = response
        result = decodeStrict (Data.ByteString.Char8.pack rawJSON) :: Maybe Object
    in case result of
        Nothing -> "Invalid JSON!"
        Just info -> WeatherValues temp_min (getTempMin info)

getTempMin :: Object -> Text
getTempMin info =
    case parseMaybe extractTempMin info of
        Nothing -> ""
        Just info -> info
    where
        extractTempMin = \info -> info .: "main"
                         >>=
                         \mainInfo -> mainInfo .: "temp_min"

2 个答案:

答案 0 :(得分:1)

让我们专注于代码中给您错误的部分。

您知道如何将String转换为Maybe Object。我将把它提取到自己的函数中,以便我们可以讨论类型。

convert :: String -> Maybe Object
convert rawJSON =  decodeStrict (Data.ByteString.Char8.pack rawJSON)

然而,在extractValues中,您提供的是Response String,而不是String。这些是根本不同的类型,就像Maybe IntInt一样。

如果你尝试convert response,编译器会因为这种类型不匹配而向你抱怨,所以我们需要做别的东西

其他的内容在很大程度上取决于Response的API。我假设它在AskWeather中定义,所以我只能猜测,但这里有一些可能适用的常见模式,具体取决于API是什么。

  • 如果AskWeather中有Response a -> aResponse String -> String类型的函数,那么我们需要在响应上调用该函数来提取{{1来自String

    Response String
  • 如果withExtract :: (Response String -> String) -> Response String -> Maybe Object withExtract extract response = convert (extract response) Functor,则可能无法从Response中提取String,但我们可以使用Response String将它包含的fmap更改为其他类型。这意味着返回值仍将包含在String

    Response

答案 1 :(得分:1)

根据Network.HTTP.Client,有一个功能

create event alert_2 ON SCHEDULE EVERY 300 SECOND DO 
BEGIN
DECLARE current_time DATETIME;
DECLARE attempted INT;
DECLARE completed INT;
DECLARE calc_value DECIMAL;
set @current_time = CONVERT_TZ(NOW(), @@session.time_zone, '+0:00');
select count(uniqueid) as @attempted,SUM(CASE WHEN seconds > 0 THEN 1 ELSE 0 END) as @completed from callinfo where date >= DATE_SUB(@current_time, INTERVAL 300 SECOND) AND date <= @current_time;
SET @calc_value = (ROUND((@completed/@attempted)*100,2);
IF @calc_value <= 10.00 THEN
     INSERT INTO report(value1) value (@calc_value);
END IF;
END;

请注意,上面的CREATE TABLE `callinfo` ( `uniqueid` varchar(60) NOT NULL DEFAULT '', `accountid` int(11) DEFAULT '0', `type` tinyint(1) NOT NULL DEFAULT '0', `callerid` varchar(120) NOT NULL, `callednum` varchar(30) NOT NULL DEFAULT '', `seconds` smallint(6) NOT NULL DEFAULT '0', `trunk_id` smallint(6) NOT NULL DEFAULT '0', `trunkip` varchar(15) NOT NULL DEFAULT '', `callerip` varchar(15) NOT NULL DEFAULT '', `disposition` varchar(45) NOT NULL DEFAULT '', `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `debit` decimal(20,6) NOT NULL DEFAULT '0.000000', `cost` decimal(20,6) NOT NULL DEFAULT '0.000000', `provider_id` int(11) NOT NULL DEFAULT '0', `pricelist_id` smallint(6) NOT NULL DEFAULT '0', `package_id` int(11) NOT NULL DEFAULT '0', `pattern` varchar(20) NOT NULL, `notes` varchar(80) NOT NULL, `invoiceid` int(11) NOT NULL DEFAULT '0', `rate_cost` decimal(20,6) NOT NULL DEFAULT '0.000000', `reseller_id` int(11) NOT NULL DEFAULT '0', `reseller_code` varchar(20) NOT NULL, `reseller_code_destination` varchar(80) DEFAULT NULL, `reseller_cost` decimal(20,6) NOT NULL DEFAULT '0.000000', `provider_code` varchar(20) NOT NULL, `provider_code_destination` varchar(80) NOT NULL, `provider_cost` decimal(20,6) NOT NULL DEFAULT '0.000000', `provider_call_cost` decimal(20,6) NOT NULL, `call_direction` enum('outbound','inbound') NOT NULL, `calltype` enum('STANDARD','DID','FREE','CALLINGCARD') NOT NULL DEFAULT 'STANDARD', `profile_start_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `answer_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `bridge_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `progress_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `progress_media_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `end_stamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `billmsec` int(11) NOT NULL DEFAULT '0', `answermsec` int(11) NOT NULL DEFAULT '0', `waitmsec` int(11) NOT NULL DEFAULT '0', `progress_mediamsec` int(11) NOT NULL DEFAULT '0', `flow_billmsec` int(11) NOT NULL DEFAULT '0', `is_recording` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0 for On,1 for Off' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='callinfo'; ALTER TABLE `callinfo` ADD UNIQUE KEY `uniqueid` (`uniqueid`), ADD KEY `user_id` (`accountid`); 可以是您想要的任何类型,因此您可以根据需要使用此功能将responseBody :: Response body -> body 转换为body

(我现在看到这已经在@jkeuhlen的评论中提出,该评论指出了相关的文档。)