我正试图找到一种方法来做这样的事情:
(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)
在这种情况下,它编译并运行得很好。
答案 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的通用版本相同,它将为您提供您正在寻找的行为。