一个无点函数可以返回一个元组吗?例如,以下内容可以用无点样式编写(其中f1,f2和f3已定义):
(\t -> (f1 t, f2 t, f3 t))
在这种情况下,我的f1,f2和f3是quot,mod,*和一些整数的组合。
(\f1,f2,f3 -> (\t -> (f1 t, f2 t, f3 t)))
是更一般的情况,相当于
(\f1,f2,f3,t -> (f1 t, f2 t, f3 t))
命名函数没问题,但我的示例是匿名的。 (命名示例如下)
f x = (f1 x, f2 x, f3 x)
f f1 f2 f3 x = (f1 x, f2 x, f3 x)
编辑:我只是好奇好玩,我不打算这样做。
答案 0 :(得分:11)
你可以写
(\t -> (f1 t, f2 t, f3 t))
pointfree,它是
liftM (,,) f1 `ap` f2 `ap` f3
来自ap
的{{1}}和来自Control.Monad
的{{1}} Monad
个实例。更可读的形式可能是(->) a
变体
Control.Monad.Instances
然后你可以进一步指向免费
Control.Applicative
作为
(,,) <$> f1 <*> f2 <*> f3
但严重的是,你不应该这样做。保持可读性,这意味着一点点自由是好的,但不要过度。
答案 1 :(得分:4)
是。 &#34; lambdabot&#34; #haskell IRC频道上的IRC bot实际上有一个功能,可以为您提供给定功能的无点版本。在你的情况下,它说
\x -> (f x, g x, h x)
相当于
ap (liftM2 (,,) f g) h
答案 2 :(得分:4)
尽管applicative或monadic版本更简单,更短,但是一种可能暴露“含义”(以及你正在使用的Haskell类型的属性)的方法是使用Control.Arrow
uncurry (uncurry (,,)) . ((f &&& g) &&& h)
有点版本虽然优越。
这也暴露了你需要Hask的“笛卡尔”,但不是Hask的所有“封闭性”
arrowized :: Arrow cat => cat a a1 -> cat a b1 -> cat a b -> cat a (a1, b1, b)
arrowized f g h => arr (uncurry (uncurry (,,))) . ((f &&& g) &&& h)
答案 3 :(得分:2)
你可以像这样编写你的例子:
\f1 f2 f3 t -> (,,) (f1 t) (f2 t) (f3 t)
(,,)是一个带有3个参数的常用函数,因此在使其应用程序无点时没有什么特别之处。但是,它使用它的参数3次,所以它会很麻烦,而且可能不值得。
#haskell的Lambdabot说它是(ap .) . liftM2 (,,)
。享受:)
答案 4 :(得分:2)
这里有一些关于对方答案的详细说明。
在Control.Applicative
的源代码中,我们找到了
instance Applicative ((->) a) where -- (a ->) is meant here
pure = const
(<*>) f g x = f x (g x)
liftA3 f a b c = f <$> a <*> b <*> c
在GHCi中,我们得到了
Prelude Control.Applicative> :t liftA3 (,,)
liftA3 (,,) :: (Applicative f) => f a -> f b -> f c -> f (a, b, c)
因此,(t->)
为f
, liftA3 (,,)
正常运作:
liftA3 (,,) ~ (t->a) -> (t->b) -> (t->c) -> (t->(a,b,c))
即,在同一类型输入上给出三个函数时,调用 liftA3 (,,) f1 f2 f3 t
会产生三个(f1 t, f2 t, f3 t)
:
Prelude Control.Applicative>
liftA3 (,,) (:[]) (quot 12) (`rem`3) 4
([4],3,1)
那么,它是如何运作的?通过liftA3
的定义,然后是<*>
的定义,
liftA3 (,,) f g h t = ((((,,) <$> f) <*> g) <*> h) t
= (((,,) <$> f) <*> g) t (h t)
= (((,,) <$> f) t (g t) (h t)
现在,(<$>) = fmap
和instance Functor ((->) t)
定义了fmap = (.)
,所以我们继续
= (((,,) . f) t (g t) (h t)
= (,,) (f t) (g t) (h t)
= (f t, g t, h t)