不确定如何将 monadic 值分配给 Aeson 对
Unsure how to assign monadic value to Aeson pair
考虑以下代码:
S.get "/budget/:bid/month/:mnth" $ do
mbid <- param "bid"
(budget :: Maybe Budget) <- liftIO $ getBudget $ toSqlKey mbid
(categories :: [Entity Category]) <- liftIO $ getCategories $ toSqlKey mbid
case budget of
Nothing -> json $ object [ "message" .= ("No budget was found!" :: String) ]
Just b -> do
json $ object [
"categoryExpenditures" .= map (\x -> object ["spent" .= liftIO $
calculateCategoryBalanceForMonth (entityKey x) 1 >>= (\y -> y) ]) categories
]
到目前为止,calculateCategoryBalanceForMonth
的类型为 calculateCategoryBalanceForMonth :: CategoryId -> Int -> IO Double
。
我正在尝试将 categories
和 return 的 categoryExpenditures
列表映射为 Aeson 中的 JSON 对象。但是,我无法弄清楚如何 return 从 liftIO
到 .=
运算符的值。
我的尝试涉及将赋值运算符脱糖为 >>= (\y -> y)
或 >>= id
,我希望 id
会 return 一个 Double,或者至少有一个实例ToJSON
。不过,情况似乎并非如此。
我也知道对 liftIO
表达式使用赋值运算符,然后将赋值的变量传递给 .=
运算符是可行的,但是我不确定如何在一个表达式中使用赋值运算符地图的匿名函数。
我可能做错了什么?还需要更清楚吗?
我假设您正在使用底部 IO
的 monad 堆栈。
object
将 [Pair]
作为参数,但是您试图将其传递给 IO
。 (>>=)
将东西 保留在 monad 中(根据定义!),所以 (>>= id)
不会按照你的意愿去做(事实上, [=16 的签名=] 是 Monad m => m (m a) -> m a
,因此 join
)。您想稍微移动一下:
Just b -> do
expenditures <- forM categories (\x -> do
spent <- liftIO $ calculateCategoryBalanceForMonth (entityKey x) 1
return $ object [ "spent" .= spent ])
json $ object [ "categoryExpenditures" .= expenditures ]
对于具有一元结果的映射,请使用 mapM
或 forM
(forM = flip mapM
)。
考虑以下代码:
S.get "/budget/:bid/month/:mnth" $ do
mbid <- param "bid"
(budget :: Maybe Budget) <- liftIO $ getBudget $ toSqlKey mbid
(categories :: [Entity Category]) <- liftIO $ getCategories $ toSqlKey mbid
case budget of
Nothing -> json $ object [ "message" .= ("No budget was found!" :: String) ]
Just b -> do
json $ object [
"categoryExpenditures" .= map (\x -> object ["spent" .= liftIO $
calculateCategoryBalanceForMonth (entityKey x) 1 >>= (\y -> y) ]) categories
]
到目前为止,calculateCategoryBalanceForMonth
的类型为 calculateCategoryBalanceForMonth :: CategoryId -> Int -> IO Double
。
我正在尝试将 categories
和 return 的 categoryExpenditures
列表映射为 Aeson 中的 JSON 对象。但是,我无法弄清楚如何 return 从 liftIO
到 .=
运算符的值。
我的尝试涉及将赋值运算符脱糖为 >>= (\y -> y)
或 >>= id
,我希望 id
会 return 一个 Double,或者至少有一个实例ToJSON
。不过,情况似乎并非如此。
我也知道对 liftIO
表达式使用赋值运算符,然后将赋值的变量传递给 .=
运算符是可行的,但是我不确定如何在一个表达式中使用赋值运算符地图的匿名函数。
我可能做错了什么?还需要更清楚吗?
我假设您正在使用底部 IO
的 monad 堆栈。
object
将 [Pair]
作为参数,但是您试图将其传递给 IO
。 (>>=)
将东西 保留在 monad 中(根据定义!),所以 (>>= id)
不会按照你的意愿去做(事实上, [=16 的签名=] 是 Monad m => m (m a) -> m a
,因此 join
)。您想稍微移动一下:
Just b -> do
expenditures <- forM categories (\x -> do
spent <- liftIO $ calculateCategoryBalanceForMonth (entityKey x) 1
return $ object [ "spent" .= spent ])
json $ object [ "categoryExpenditures" .= expenditures ]
对于具有一元结果的映射,请使用 mapM
或 forM
(forM = flip mapM
)。