是否可以在Haskell中的列表上映射函数元组?

时间:2012-07-27 19:15:44

标签: function haskell tuples applicative

我正试图找到一种方法来做这样的事情:

(head, last) `someFunction` [1, 2, 3]

生成元组(1, 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)

在这种情况下,它编译并运行得很好。

4 个答案:

答案 0 :(得分:15)

我认为你可以用箭头做到这一点。

head &&& last $ [1,2,3]

将返回(1,3)

答案 1 :(得分:9)

  

它在理论上似乎与应用仿函数相似,但略微向后。

实际上,它是一个无聊的旧前锋应用程序;特别是读者((->) r)

Prelude Control.Applicative> liftA2 (,) head last [1,2,3]
(1,3)

或者,如果你是这样的话:

Prelude Control.Applicative> let sequenceA [] = pure []; sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
Prelude Control.Applicative> [head, last] `sequenceA` [1,2,3]
[1,3]

答案 2 :(得分:4)

fmap'的类型错误。它应该是

fmap' :: ([a] -> b, [a] -> b) -> [a] -> (b, b)

或者,它可以更通用

fmap' :: (a -> b, a -> c) -> a -> (b, c)

它与fmap :: (a -> b) -> f a -> f b并不相似。

答案 3 :(得分:3)

在这种情况下尝试的是省略类型签名并检查GHC推断的内容。

这样做并询问GHCi :t fmap'会产生签名

fmap' :: (t2 -> t, t2 -> t1) -> t2 -> (t, t1)

与KennyTM的通用版本相同,它将为您提供您正在寻找的行为。