Haskell 泛化函数以折叠具有一个更高种类类型和两个嵌套类型的两个元素?

Haskell 泛化函数以折叠具有一个更高种类类型和两个嵌套类型的两个元素?,haskell,polymorphism,composition,higher-kinded-types,Haskell,Polymorphism,Composition,Higher Kinded Types,我有以下两个要素: x :: Maybe t y :: [(String, t)] 我有一个功能: foo :: t -> a 如何使用foo实现多态函数,既可以在x上工作,也可以在y上工作,以收集列表中的结果?更具体地说,我需要在这里放置一些内容,而不是?: mapToList :: ??? => (t -> a) -> ??? t -> [a] 我想用更少的样板打电话,最好是最接近这一点的选项: mapToList foo x mapToList foo

我有以下两个要素:

x :: Maybe t
y :: [(String, t)]
我有一个功能:

foo :: t -> a
如何使用
foo
实现多态函数,既可以在
x
上工作,也可以在
y
上工作,以收集列表中的结果?更具体地说,我需要在这里放置一些内容,而不是

mapToList :: ??? => (t -> a) -> ??? t -> [a]
我想用更少的样板打电话,最好是最接近这一点的选项:

mapToList foo x
mapToList foo y
像这样幼稚的事情是行不通的:(


我一直在看,但没能想出如何用简单的方法把它应用到我的问题上。我可以用
Compose
以某种方式概括,但我的解决方案并不令人满意。我总是可以用
map
来处理列表,只是
也许[]foo
上可能是
。但是我想知道,有没有好的方法来概括这两个用例?

不确定这是否有帮助,因为它只是将样板文件从调用站点移开,但是:

{-# 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

我认为如果合理的话,
mapToList foo(Compose y)
将与您的
mapToList
定义一起工作。
Compose y
将具有类型
Compose[](,)字符串)t
。我更喜欢你的解决方案,它是
组合的
。这可能是我用一般方法所能想象到的最不可能的样板文件。但它可以用相反的方法来完成吗?例如,我大部分都有列表,只有很少的
可能
。我是否可以以某种方式扁平化或忽略类型,只为
可能
指定类型?你可以使用
>mapToList f=concatMap(map f.toList)
类型
mapToList::(Foldable f)=>(t->a)->[f t]->[a]
并将您的
值包装在
[]
中。或者您可以使用
(Foldable fo,Foldable fi)=>fo(fi t)
和一个额外的
toList
调用并将其包装在任何
Foldable
Identity
),我可能更喜欢列表版本,除非真正需要通用性。
{-# 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