源 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]
,但您可以将 totalLoss
与 items
通过 do
表示法。
如果你不想依赖 do
符号,你也可以在没有语法糖的情况下编写你的函数:
main :: IO ()
main = fmap totalLoss ioItems >>= print
main
的这两个变体是等价的。
关于list - 将函数应用于自定义数据结构列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56619840/