List 来自(a->;[b])->;[a->;b]

List 来自(a->;[b])->;[a->;b],list,function,haskell,List,Function,Haskell,我有一个函数separatefuncs,这样 seperateFuncs :: [a -> b] -> (a -> [b]) seperateFuncs xs = \x -> map ($ x) xs 我想知道是否存在相反的情况,即是否存在函数 joinFuncs :: (a -> [b]) -> [a -> b] 我认为不是(主要是因为列表不是固定长度的),但也许我会被证明是错的。 那么问题是有一些数据类型f有一个函数::(a->fb)->f(a-

我有一个函数
separatefuncs
,这样

seperateFuncs :: [a -> b] -> (a -> [b])
seperateFuncs xs = \x -> map ($ x) xs
我想知道是否存在相反的情况,即是否存在函数

joinFuncs :: (a -> [b]) -> [a -> b]
我认为不是(主要是因为列表不是固定长度的),但也许我会被证明是错的。
那么问题是有一些数据类型
f
有一个函数::(a->fb)->f(a->b)?

首先,你可以强制自己使用这个函数好了:

joinFuncs f = [\x -> f x !! i | i<-[0..]]
joinFuncs f=[\x->fx!!i | i i

给出一个“真正”的解决方案

接下来的问题是是否有一些数据类型
f
具有函数
:(a->fb)->f(a->b)

考虑一下
(>)c
。这样,你的签名就变成了
(a->(c->b))->(c->(a->b))
,或者相当于
(a->c->b)->c->a->b
,结果就是
翻转


当然,这有点琐碎,因为
separatefuncs
对此类型具有相同的签名…

您可以非常清晰地将
separatefuncs
概括为
Applicative
(或
Monad
):

seperateFuncs :: (Applicative f) => f (a -> b) -> (a -> f b)
seperateFuncs f x = f <*> pure x
这里我将
unlictaive
定义为:

class Functor f => Unapplicactive f where
    extract  :: f a -> a
    unap     :: (f a -> f b) -> f (a -> b)
若要获取,可以给出以下实例:

instance Unapplicative [] where
    extract = head
    unap f = [\a -> f [a] !! i | i <- [0..]]

instance Unapplicative ((->) c) where
    extract f = f undefined
    unap f = \x y -> f (const y) x
实例不适用[],其中
提取=头
unap f=[\a->f[a]!!i | i)c)其中
提取f=f未定义
unap f=\x y->f(常数y)x
我认为很难想出一个“有用的”函数
f:(fa->fb)->f(a->b)
对于任何
f
不像
(>)

“是否有一些数据类型f有一个函数::(a->fb)->f(a->b)

事实上,type类中有一个更通用的函数版本,它处理可交换函子:

class (Functor t, Foldable t) => Traversable t where

  ... 

  sequenceA :: Applicative f => t (f b) -> f (t b)
这与您的功能有什么关系?从您的类型开始,使用一个类型替换,我们恢复
sequenceA

  • (a->fb)->f(a->b)
    ==>
    让t=(>)a
  • t(fb)->f(tb)

  • 但是,这种类型有一个约束,即
    t
    必须是可遍历的,并且
    (>)a
    没有可遍历的实例,这意味着这个操作通常不能用函数来完成适用于所有函数和所有应用程序
    f

    我最近不得不考虑一些问题,这些问题与您的问题非常相似。以下是我发现的概括

    首先,这样做很简单(Tintorius指出):

    但一般来说,这是不可能做到的:

    m2a :: Monad m => (a -> m b) -> m (a -> b)
    
    有人在哈斯克尔irc频道向我解释了一种深刻的理解方法,即如果存在
    m2a
    函数,那么
    Applicative
    Monad
    之间就没有区别。为什么?我不是100%地理解它,但它是这样的:
    Monad m=>a->mbde>是一个参数的一元操作的非常常见的类型,而
    Applicative f=>f(a->b)
    也是非常常见的类型,因为不知道正确的名称,我将其称为“Applicative applications”而
    Monad
    可以做
    Applicative
    做不到的事情,这一事实与
    m2a
    不存在这一事实相联系

    现在,应用到你的问题上:

    joinFuncs :: (a -> [b]) -> [a -> b]
    
    我怀疑同样的“Monad/=Applicative”参数(我再次强调,我不完全理解)应该在这里应用。我们知道
    Monad[]
    实例可以做
    Applicative[]
    实例不能做的事情。如果您可以用指定的类型编写
    joinFuncs
    ,那么
    [a->b]
    a->[b]
    参数相比,结果在某种意义上必须是“丢失信息”,因为除此之外
    Applicative[]
    Monad[]
    是相同的(通过“丢失”信息我的意思是,任何具有
    joinFuncs
    类型的函数都不能有一个逆函数,因此它保证消除某些函数对
    f,g::a->[b]
    之间的区别。这种情况的极端情况是
    joinFuncs=undefined

    我确实发现我需要类似于
    m2a
    的函数,因此我发现的特殊情况是可以这样做:

    import Data.Map (Map)
    import qualified Data.Map as Map
    
    -- | Enumerate a monadic action within the domain enumerated by the 
    -- argument list.
    boundedM2a :: Monad m => (a -> m b) -> [a] -> m [(a,b)]
    boundedM2a f = mapM f'
        where f' a = do b <- f a
                        return (a, b)
    
    -- | The variant that makes a 'Map' is rather useful.
    boundedM2a' :: (Monad m, Ord a) => (a -> m b) -> [a] -> m (Map a b)
    boundedM2a' f = liftM Map.fromList . boundedM2a f
    
    导入数据.Map(Map)
    导入符合条件的数据。映射为映射
    --|枚举由
    --参数列表。
    boundedM2a::单子m=>(a->MB)->[a]->m[(a,b)]
    boundedM2a f=mapM f'
    其中f'a=do b问题“我可以拥有类型签名为
    joinFuncs::(a->[b])->[a->b]
    的函数吗?如果没有说明您希望该函数满足哪些规则,则该问题是不完整的。如果没有规则,您可以通过定义
    joinFuncs.[]
    (始终返回空列表)来解决此问题。此普通函数满足所需的类型签名,但很可能是无用的

    要求
    joinFuncs
    有用的一种方法是施加非简并定律,
    separateFuncs.joinFuncs==id
    。然后可以证明,对于这种类型的签名,不可能实现
    joinFuncs

    这种类型签名的更一般的情况是
    (A->fb)->f(A->b)
    ,其中
    f
    是一些函子。我称这种函子为“刚性”。有关详细信息,请参阅此问题

    所有刚性函子
    R
    都满足这样一个属性,即类型
    R()
    只有一个不同的值,即它等价于
    ()
    。这允许我们立即看到
    列表
    函子不是刚性的,因为
    列表()
    不等价于
    ()

    刚性函子最简单的例子是
    ra=(a->p)->a
    ,其中
    p
    是固定类型
    joinFuncs :: (a -> [b]) -> [a -> b]
    
    import Data.Map (Map)
    import qualified Data.Map as Map
    
    -- | Enumerate a monadic action within the domain enumerated by the 
    -- argument list.
    boundedM2a :: Monad m => (a -> m b) -> [a] -> m [(a,b)]
    boundedM2a f = mapM f'
        where f' a = do b <- f a
                        return (a, b)
    
    -- | The variant that makes a 'Map' is rather useful.
    boundedM2a' :: (Monad m, Ord a) => (a -> m b) -> [a] -> m (Map a b)
    boundedM2a' f = liftM Map.fromList . boundedM2a f