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