You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell函数extractValues类型匹配错误求助:Response String与[Char]不匹配

解决Haskell中Response String与[Char]类型不匹配问题

咱们先拆解一下你遇到的两个类型错误,然后一步步修复代码:

错误根源分析

  1. 第一个类型不匹配:错误提示Couldn't match type ‘Response String’ with ‘[Char]’,是因为你直接把Response String类型的response变量当成了普通String来用。Response是HTTP客户端返回的完整响应对象,包含状态码、请求头和响应体等信息,你需要用responseBody函数提取其中的字符串内容。
  2. 第二个类型不匹配:你的extractValues函数签名要求返回WeatherValues,但在case result of的Nothing分支里返回了字符串"Invalid JSON!",这和函数的返回类型完全不兼容,Haskell肯定会报错。
  3. 额外小问题:构造WeatherValues时,你错误地写了WeatherValues temp_min (getTempMin info)——temp_min是记录的字段名,不是值,而且WeatherValues需要两个参数(最低温和最高温),你只传了一个。

修复后的完整代码

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module PrepareAnswer where
import Data.Text
import Data.Aeson
import Network.HTTP.Client (Response(..))  -- 明确导入responseBody所需的类型和函数
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函数
extractValues :: Response String -> WeatherValues
extractValues response = let
    rawJSON = responseBody response  -- 用responseBody提取响应体的字符串内容
    jsonBytes = Data.ByteString.Char8.pack rawJSON  -- 转成decodeStrict需要的ByteString
    result = decodeStrict jsonBytes :: Maybe Object
  in case result of
    -- 返回默认空值的WeatherValues,保证类型匹配
    Nothing -> WeatherValues "" ""
    -- 正确传入最低温和最高温的字段值
    Just info -> WeatherValues (getTempMin info) (getTempMax info)

getTempMin :: Object -> Text
-- 用fromMaybe简化空值处理
getTempMin info = fromMaybe "" (parseMaybe extractTempMin info)
  where extractTempMin = \info -> info .: "main" >>= \mainInfo -> mainInfo .: "temp_min"

-- 补充获取最高温的函数
getTempMax :: Object -> Text
getTempMax info = fromMaybe "" (parseMaybe extractTempMax info)
  where extractTempMax = \info -> info .: "main" >>= \mainInfo -> mainInfo .: "temp_max"

关键修改点说明

  1. 提取响应体:导入Network.HTTP.Client (Response(..))后,用responseBody response获取真正的JSON字符串内容,解决了第一个类型不匹配问题。
  2. 统一返回类型:把Nothing分支的返回值改成WeatherValues "" "",确保和函数签名的返回类型一致。
  3. 完善数据构造:补充getTempMax函数,并在构造WeatherValues时正确传入两个字段的值。
  4. 简化空值处理:用fromMaybe ""替代冗余的case表达式,让代码更简洁。

更严谨的错误处理方案(可选)

如果想让调用者明确知道JSON解析或字段提取是否失败,可以把extractValues的返回类型改成Maybe WeatherValues:

extractValues :: Response String -> Maybe WeatherValues
extractValues response = let
    rawJSON = responseBody response
    jsonBytes = Data.ByteString.Char8.pack rawJSON
    result = decodeStrict jsonBytes :: Maybe Object
  in result >>= \info -> do
       minTemp <- parseMaybe extractTempMin info
       maxTemp <- parseMaybe extractTempMax info
       return $ WeatherValues minTemp maxTemp
  where
    extractTempMin = \info -> info .: "main" >>= \mainInfo -> mainInfo .: "temp_min"
    extractTempMax = \info -> info .: "main" >>= \mainInfo -> mainInfo .: "temp_max"

这种方式下,任何环节失败都会返回Nothing,调用者可以根据这个结果做针对性的错误处理。

内容的提问来源于stack exchange,提问作者MixFix Chanel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:00:57