如何将 [Maybe Text] 与镜头连接起来?
How to concatenate [Maybe Text] with lenses?
有没有办法用镜头写出下面的...
[Maybe Text] -> Text
...大概可以归纳为:
(Monoid a, Traversable t) => t a -> a
我正在尝试做的具体示例:
[Just "abc", Nothing, Just "def"] -> "abcdef"
[Nothing, Nothing] -> ""
PS:我假设镜头有一些时髦的组合器可以做到这一点。如果我对镜头的出色表现感到措手不及,而这可以通过更简单的组合器轻松实现,请告诉我。
您的 (Monoid a, Traversable t) => t a -> a
函数可以进一步概括为简单的 fold :: (Foldable f, Monoid a) => f a -> a
。
例如:
Prelude> import Data.Foldable
Prelude Data.Foldable> fold [Just "abc", Nothing, Just "def"]
Just "abcdef"
我们可以将它从 Maybe
中解包出来:
import Data.Foldable(fold, mempty)
import Data.Maybe(maybe)
foldMaybe :: (Foldable f, Monoid a) => f (Maybe a) -> a
foldMaybe = fromMaybe mempty . fold
例如:
Prelude Data.Foldable Data.Maybe> foldMaybe [Just "abc", Nothing, Just "def"]
"abcdef"
Prelude Data.Foldable Data.Maybe> foldMaybe [Nothing] :: String
""
作为 Willem 解决方案的变体,我更喜欢双 fold
(一个用于列表,另一个用于 Maybe
):
> fold . fold $ [Just "abc", Nothing, Just "def"]
"abcdef"
其实fold = maybe mempty id = fromMaybe mempty
换Maybe
,所以真的是一样的
它的一般类型是:
fold . fold :: (Monoid a, Foldable t1, Foldable t2, Monoid (t1 a)) => t2 (t1 a) -> a
完全适用于 [Maybe a]
.
@dfeuer 在下面建议的另一个不错的解决方案:
foldMap fold
此处,fold
删除了 Just
包装器,同时将 Nothing
替换为空字符串。然后,foldMap
连接所有结果字符串。
答案只是一个折叠,所以你可以 "use lenses" 以一种愚蠢的方式使用 foldOf
foldOf :: Monoid a => Fold s a -> s -> a
所以如果你能找到一个 myFold :: Fold (t a) a
,你可以将它与 foldOf
一起使用以获得:
foldOf myFold :: Monoid a => t a -> a
幸运的是,对于 Foldable t
的任何实例,我们都可以访问 folded :: Fold (t a) a
。所以我们可以使用 foldOf
和 folded
:
foldOf :: Monoid a => Fold s a -> s -> a
folded :: Foldable t => Fold (t a) a
foldOf folded :: (Foldable t, Monoid a) => t a -> a
有没有办法用镜头写出下面的...
[Maybe Text] -> Text
...大概可以归纳为:
(Monoid a, Traversable t) => t a -> a
我正在尝试做的具体示例:
[Just "abc", Nothing, Just "def"] -> "abcdef"
[Nothing, Nothing] -> ""
PS:我假设镜头有一些时髦的组合器可以做到这一点。如果我对镜头的出色表现感到措手不及,而这可以通过更简单的组合器轻松实现,请告诉我。
您的 (Monoid a, Traversable t) => t a -> a
函数可以进一步概括为简单的 fold :: (Foldable f, Monoid a) => f a -> a
。
例如:
Prelude> import Data.Foldable
Prelude Data.Foldable> fold [Just "abc", Nothing, Just "def"]
Just "abcdef"
我们可以将它从 Maybe
中解包出来:
import Data.Foldable(fold, mempty)
import Data.Maybe(maybe)
foldMaybe :: (Foldable f, Monoid a) => f (Maybe a) -> a
foldMaybe = fromMaybe mempty . fold
例如:
Prelude Data.Foldable Data.Maybe> foldMaybe [Just "abc", Nothing, Just "def"]
"abcdef"
Prelude Data.Foldable Data.Maybe> foldMaybe [Nothing] :: String
""
作为 Willem 解决方案的变体,我更喜欢双 fold
(一个用于列表,另一个用于 Maybe
):
> fold . fold $ [Just "abc", Nothing, Just "def"]
"abcdef"
其实fold = maybe mempty id = fromMaybe mempty
换Maybe
,所以真的是一样的
它的一般类型是:
fold . fold :: (Monoid a, Foldable t1, Foldable t2, Monoid (t1 a)) => t2 (t1 a) -> a
完全适用于 [Maybe a]
.
@dfeuer 在下面建议的另一个不错的解决方案:
foldMap fold
此处,fold
删除了 Just
包装器,同时将 Nothing
替换为空字符串。然后,foldMap
连接所有结果字符串。
答案只是一个折叠,所以你可以 "use lenses" 以一种愚蠢的方式使用 foldOf
foldOf :: Monoid a => Fold s a -> s -> a
所以如果你能找到一个 myFold :: Fold (t a) a
,你可以将它与 foldOf
一起使用以获得:
foldOf myFold :: Monoid a => t a -> a
幸运的是,对于 Foldable t
的任何实例,我们都可以访问 folded :: Fold (t a) a
。所以我们可以使用 foldOf
和 folded
:
foldOf :: Monoid a => Fold s a -> s -> a
folded :: Foldable t => Fold (t a) a
foldOf folded :: (Foldable t, Monoid a) => t a -> a