【问题标题】:How to iterate over record fields?如何迭代记录字段?
【发布时间】:2015-10-07 17:44:41
【问题描述】:

我将以下数据类型定义为记录

data Config = Config
  { field1 :: String
  , field2 :: String
  , field3 :: String
  }

我想遍历Config 的每个字段,应用一些函数String -> String,例如tail 并返回新的Config

这样做的惯用方法是什么?最好没有繁重的第 3 方库。

【问题讨论】:

  • head 函数返回一个Char。我是否正确理解您希望字段的类型根据提供的函数返回的内容而改变?
  • uniplate 是一个轻量级的泛型库,可能很容易做到这一点。
  • @MichaelSteele 我的错,类似于tail 将返回相同的类型String。我已经更新了问题
  • tail 的情况下,@leftroundabout 的答案是可以使用的。请注意,即使您正在寻找函数 Config -> Config,您也需要在 Config 的定义中添加一个类型变量(如@leftroundabout 的回答),以便fmap 可以为您完成工作。跨度>
  • 你确定你没有通过类比来思考动态类型语言,这将是一个自然的事情。在 Haskell 中,这并非不可能,但通常数据结构的每个字段都代表不同类型的事物,因此使用不同的函数进行处理。您的结构的外观似乎建议使用字典或数组,在这种情况下 Data.Map 或 Array 可能更合适。

标签: haskell records


【解决方案1】:

嗯,最好的方法可能是

{-# LANGUAGE DeriveFunctor #-}

type Config = Config' String
data Config' a = Config
  { field1 :: a
  , field2 :: a
  , field3 :: a
  } deriving (Functor)

configHeads :: Config -> Config' Char
configHeads = fmap head

【讨论】:

  • monotraversable 将是一个替代方案。
  • 对于字符串,这似乎是显而易见的方法。不幸的是,这种方法在其他一些情况下阻止了很好的优化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
相关资源
最近更新 更多