list - 将函数应用于自定义数据结构列表

标签 list haskell

源 self 之前的问题:Calculation difference between Days 我不想将函数应用于我的自定义数据结构列表 Item .问题是我仍然不明白如何处理 IO正确的,所以这是我的代码:

data Item = Item
    { name :: String
    , expire :: Day
    , stock :: Integer
    , price :: Float
    } deriving (Show)

totalLoss :: IO [Item] -> Float
totalLoss items = sum $ map loss items

loss :: Item -> Float
loss x = (price x) * fromIntegral (stock x)

这么说吧,我不能只得到 [Item]所以我必须处理 IO恰当的。但无论我做什么,我仍然会遇到这些错误:

    • Couldn't match expected type ‘[IO Item]’
                  with actual type ‘IO [Item]’
    • In the second argument of ‘map’, namely ‘items’
      In the second argument of ‘($)’, namely ‘map loss items’
      In the expression: sum $ map loss items
   |
48 | totalLoss items = sum $ map loss items
   |                                  ^^^^^

loss :: IO Item -> Float这是同样的错误和loss :: IO [Item] -> Float我收到另一个错误。

    • Couldn't match expected type ‘[IO [Item]]’
                  with actual type ‘IO [Item]’
    • In the second argument of ‘map’, namely ‘items’
      In the second argument of ‘($)’, namely ‘map loss items’
      In the expression: sum $ map loss items
   |
48 | totalLoss items = sum $ map loss items
   |                                  ^^^^^

我究竟应该如何解决这个问题?

最佳答案

totalLoss 是一个纯函数,因此相应地改变它的类型:

totalLoss :: [Item] -> Float
totalLoss items = sum $ map loss items

这个问题的根本问题似乎是项目列表的来源不纯(这是很自然的事情)。

将尽可能多的代码编写为纯函数,然后将这些纯函数与不纯输入组合到(或尽可能接近)main 函数:

main :: IO ()
main = do
  items <- ioItems -- :: IO [Item]
  print $ totalLoss items

正如注释所暗示的那样,ioItems 的类型为 IO [Item],但您可以将 totalLossitems 通过 do 表示法。

如果你不想依赖 do 符号,你也可以在没有语法糖的情况下编写你的函数:

main :: IO ()
main = fmap totalLoss ioItems >>= print

main 的这两个变体是等价的。

关于list - 将函数应用于自定义数据结构列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56619840/

相关文章:

python - 是否有返回排序列表的 list.sort() 版本?

c - 创建列表并打印其元素时出错

c# - 在类之间发送信息对象以添加到 List<T>。请帮忙!

haskell - 使用 nginx 通过 https 运行 Haskellservant

python - 从对中获取另一个元素

python - 什么时候 array.array 比列表更有效?

haskell - 什么是 Maybe 类型,它是如何工作的?

haskell - 带分隔符的秒差距置换解析器

Haskell:如何播种(设置 Data.Random 使用的熵)?

python - 从 Haskell 到 Python : multiple-functions conversion issue