在 monad 内部映射
Mapping inside monad
f1 ∷ Int → Identity (Maybe String)
f1 x = Identity $ if even x then Just (show x) else Nothing
-- f1 4 = "4", f1 5 = Nothing etc.
f2 ∷ (Int → Identity (Maybe String)) → [Int] → Identity String
-- f2 [1..10] = "246810"
现在可以使用 mapMaybeM 实现 f2 吗?
--- 编辑 ----------------------
让我试着向您展示这个问题背后的实际问题。
g1 :: Type1 -> SomeT Maybe Type2
g2 需要映射 Just 值并摆脱 Maybe:
g2 :: (Type1 -> SomeT Maybe Type2) -> [Type1] -> SomeT Identity [Type2]
mapMaybeM f1
会让你 [Int] -> Identity [String]
。然后你可以使用 fmap concat
for Identity [String] -> Identity String
来连接值。
根据您的更新,如果这有帮助的话:
f2 :: (Int -> IdentityT Maybe String) -> [Int] -> IdentityT Identity [String]
f2 f = mapIdentityT (fmap concat) . foldl (liftA2 (++)) (lift (return [])) . map (mapIdentityT (return . maybeToList) . f)
这在 IdentityT
内有效,依赖于 mapIdentityT
。我认为根本问题是 [MT M a] -> MT M [a]
并且我不确定这在一般情况下是否可行 - 它可能取决于变压器的属性。
f1 ∷ Int → Identity (Maybe String)
f1 x = Identity $ if even x then Just (show x) else Nothing
-- f1 4 = "4", f1 5 = Nothing etc.
f2 ∷ (Int → Identity (Maybe String)) → [Int] → Identity String
-- f2 [1..10] = "246810"
现在可以使用 mapMaybeM 实现 f2 吗?
--- 编辑 ----------------------
让我试着向您展示这个问题背后的实际问题。
g1 :: Type1 -> SomeT Maybe Type2
g2 需要映射 Just 值并摆脱 Maybe:
g2 :: (Type1 -> SomeT Maybe Type2) -> [Type1] -> SomeT Identity [Type2]
mapMaybeM f1
会让你 [Int] -> Identity [String]
。然后你可以使用 fmap concat
for Identity [String] -> Identity String
来连接值。
根据您的更新,如果这有帮助的话:
f2 :: (Int -> IdentityT Maybe String) -> [Int] -> IdentityT Identity [String]
f2 f = mapIdentityT (fmap concat) . foldl (liftA2 (++)) (lift (return [])) . map (mapIdentityT (return . maybeToList) . f)
这在 IdentityT
内有效,依赖于 mapIdentityT
。我认为根本问题是 [MT M a] -> MT M [a]
并且我不确定这在一般情况下是否可行 - 它可能取决于变压器的属性。