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

Rails/Ruby中dry-monads调用FakeStoreApi时提示无法遍历无类型列表

解决dry-monads中"Cannot traverse an untyped list"错误

你在测试Shftcos API样板代码时,用到了不熟悉的dry-monads gem,调用FakeStoreApi获取产品的服务请求触发了如下错误:

Cannot traverse an untyped list (StandardError)

对应的服务代码如下:

require 'faraday'
require 'json'

class FetchProductsService < ApplicationService
  def call
    result = yield fetch_products

    Success(result)
  end

  private

  def fetch_products
    products = []
    response = Faraday.get('https://fakestoreapi.com/products') 
    if response.status == 200
      products = JSON.parse(response.body)
    end
    products
  end
end 

问题原因

dry-monads的traverse操作(处理集合类型Monad时常用)要求集合是有明确类型的容器,而你当前fetch_products返回的是原生Ruby数组(Array),属于无类型列表,dry-monads无法识别它来执行traverse操作。

解决方法

1. 用dry-monads的List类型包装返回数组

dry-monads提供了Dry::Monads::List来作为有类型的集合容器,修改代码如下:

require 'faraday'
require 'json'
require 'dry/monads/list'

class FetchProductsService < ApplicationService
  include Dry::Monads::List::Mixin

  def call
    result = yield fetch_products

    Success(result)
  end

  private

  def fetch_products
    products = []
    response = Faraday.get('https://fakestoreapi.com/products') 
    if response.status == 200
      products = JSON.parse(response.body)
    end
    List(products) # 将普通数组转换为dry-monads的List类型
  end
end

2. 检查上层调用逻辑

如果是上层代码在处理FetchProductsService.call的结果时执行了traverse,也可以在那里把原生数组转为List,但更推荐在服务内部统一返回有类型容器,保证代码风格一致。

补充说明

dry-monads的设计核心就是通过有类型容器明确数据结构,避免无类型集合的不确定性,所以涉及Monad的集合操作时,必须使用它提供的List(或其他兼容有类型集合),而非原生Ruby数组。

内容的提问来源于stack exchange,提问作者Paul Anthony McGowan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:15:34