Function 是否可以在Haskell中的列表上映射函数元组?
我正试图找到一种方法来做这样的事情:Function 是否可以在Haskell中的列表上映射函数元组?,function,haskell,tuples,applicative,Function,Haskell,Tuples,Applicative,我正试图找到一种方法来做这样的事情: (head, last) `someFunction` [1, 2, 3] fmap' :: ((a -> b), (a -> b)) -> [a] -> (b, b) fmap' (f1, f2) xs = (f1 xs, f2 xs) 生成元组(1,3)作为输出 它在理论上似乎类似于应用函子,但有点倒退。我猜有一个类似的函数可以做到这一点(或者以某种方式实现),但我似乎找不到它/弄明白它 我试着定义这样一个函数: (head,
(head, last) `someFunction` [1, 2, 3]
fmap' :: ((a -> b), (a -> b)) -> [a] -> (b, b)
fmap' (f1, f2) xs = (f1 xs, f2 xs)
生成元组(1,3)
作为输出
它在理论上似乎类似于应用函子,但有点倒退。我猜有一个类似的函数可以做到这一点(或者以某种方式实现),但我似乎找不到它/弄明白它
我试着定义这样一个函数:
(head, last) `someFunction` [1, 2, 3]
fmap' :: ((a -> b), (a -> b)) -> [a] -> (b, b)
fmap' (f1, f2) xs = (f1 xs, f2 xs)
但GHC实际上不会编译这个
任何帮助都将是巨大的;谢谢
编辑(一年后!):
我的fmap'
无法编译,因为类型签名错误。显然有更好的方法来完成我正在做的事情,但是我的fmap'
的类型应该是:
fmap' :: ((a -> b), (a -> b)) -> a -> (b, b)
在这种情况下,它编译并运行得很好。fmap的类型是错误的。应该是
fmap' :: ([a] -> b, [a] -> b) -> [a] -> (b, b)
或者,它可以更一般化
fmap' :: (a -> b, a -> c) -> a -> (b, c)
它与fmap:(a->b)->fa->fb不太相似 在这种情况下,可以尝试省略类型签名并检查GHC推断的内容 这样做并询问GHCi
:t fmap'
将生成签名
fmap' :: (t2 -> t, t2 -> t1) -> t2 -> (t, t1)
这与KennyTM的广义版本相同,并将为您提供所需的行为。我认为您可以使用箭头来实现这一点
head &&& last $ [1,2,3]
将返回(1,3)
它在理论上似乎类似于应用函子,但有点倒退
事实上,这是一个无聊的函数;具体地说,读取器((->)r)
或者,如果你对这类事情感兴趣:
Prelude Control.Applicative> let sequenceA [] = pure []; sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
Prelude Control.Applicative> [head, last] `sequenceA` [1,2,3]
[1,3]
Prelude Control.Applicative>let sequenceA[]=pure[];sequenceA(x:xs)=(:)x sequenceA xs
前奏曲控制.Applicative>[head,last]`sequenceA`[1,2,3]
[1,3]
啊!实际上,我尝试了一些不起作用的方法,但我刚刚意识到我调用的是fmap
,而不是fmap'
。我想知道为什么它不能正常工作。感谢您的快速回复!根据pointfree
,原来someFunction
是uncurry(liftM2(,)
)。当然,您可以省去uncurry
,只使用剩下的:liftM2(,)head last[1,2,3]
。我还不熟悉箭头,但我一直希望了解并更多地使用它们。这是好的和可读的。谢谢有人知道如何将其推广到两个以上的函数吗?例如,head&&last&&tail
会给您(1,(3,[2,3])
,这并不理想。有没有一种简单的方法可以将其展平为一个元组?@JeffreyBurka我也经历过这种情况。我认为tuple
-扁平化函数会违反Haskell的严格类型系统,因为n-tuple
是n-tuple
,仅此而已。该函数的类型签名没有意义(您必须输出一个动态大小的元组,这是不可能的。)是的,元组肯定没有concat
,但我想可能有一种简单的方法将箭头表示为一个返回3元组而不是嵌套元组的箭头。如果这不可能或不容易,那么我就使用Daniel Wagner的应用程序解决方案。实际上,我认为使用它可能足够简单。我现在没有GHC,很不幸,Codepad使用拥抱,所以我现在无法测试。