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