我接下来有两个要素:
x :: Maybe t
y :: [(String, t)]
我有一个功能:
foo :: t -> a
如何实现可以在x
和y
上使用foo
同时在列表中收集结果的多态函数?更具体地说,我需要在这里添加一些代替???
的东西:
mapToList :: ??? => (t -> a) -> ??? t -> [a]
我希望用更少的样板来调用,最优选的选项最好:
mapToList foo x
mapToList foo y
像这样天真的东西不起作用:(
mapToList :: Foldable f => (t -> a) -> f t -> [a]
mapToList extractor = map extractor . toList
mapToList @Maybe foo x
mapToList @([] ((,) String)) foo y
我在看Get user membership groups in the claims with AD B2C,但没有设法弄清楚如何以简单的方式将它应用到我的问题中。我可以使用Compose
来概括以某种方式,但我的解决方案并不令人满意。我可以随时使用map
列表,maybe [] foo
只使用Maybe
。但是我想知道,有没有很好的方法来推广这两个用例?
答案 0 :(得分:1)
不确定这有什么用处,因为它只是将样板移离呼叫站点,但是:
{-# LANGUAGE FlexibleInstances,FunctionalDependencies,RankNTypes #-}
import Data.Functor.Compose (Compose(Compose))
import Data.Foldable
class AsFoldable x a | x -> a where
withFoldable :: (forall f. (Foldable f) => f a -> b) -> x -> b
instance AsFoldable [(String,a)] a where
withFoldable f = f . Compose
instance AsFoldable (Maybe a) a where
withFoldable = id
x :: Maybe Int
x = Just 3
y :: [(String,Int)]
y = [("A",5),("B",6)]
mapToList :: (AsFoldable x t) => (t -> a) -> x -> [a]
mapToList f = withFoldable (map f . toList)
main = do
print $ mapToList (+1) x
print $ mapToList (+1) y