无点返回Haskell中的元组
无点函数能否返回元组?例如,可以用无点样式编写以下内容(其中定义了f1、f2和f3): 在本例中,我的f1、f2和f3是quot、mod、*和一些整数的组合无点返回Haskell中的元组,haskell,pointfree,Haskell,Pointfree,无点函数能否返回元组?例如,可以用无点样式编写以下内容(其中定义了f1、f2和f3): 在本例中,我的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)) ap (liftM2 (,,) f g) h 命名函数是可以的,但我的示例是匿名的。(命名示例如下) 编辑:我只是好奇好玩,我不打算这么做
(\f1,f2,f3 -> (\t -> (f1 t, f2 t, f3 t)))
是更一般的情况,相当于
(\f1,f2,f3,t -> (f1 t, f2 t, f3 t))
ap (liftM2 (,,) f g) h
命名函数是可以的,但我的示例是匿名的。(命名示例如下)
编辑:我只是好奇好玩,我不打算这么做。是的。#haskell IRC频道上的“lambdabot”IRC bot实际上有一个功能,可以为您提供给定函数的无点版本。在你的情况下,它说
\x -> (f x, g x, h x)
相当于
(\f1,f2,f3,t -> (f1 t, f2 t, f3 t))
ap (liftM2 (,,) f g) h
你可以写
(\t -> (f1 t, f2 t, f3 t))
无意义的,它是
liftM (,,) f1 `ap` f2 `ap` f3
使用Control.Monad
中的ap
和Control.Monad.Instances中的Monad
实例(>)a
。一种更具可读性的形式可能是控件.Applicative
变体
(,,) <$> f1 <*> f2 <*> f3
作为
\f1 f2 f3->(,)f1 f2 f3
=\f1 f2->((,)f1 f2)
=\f1 f2->()((,)f1 f2)
=\f1 f2->(()。(,)f1))f2
=\f1->()。(,)f1)
=\f1->()。()(,)f1)
=\f1->((()).()(,)f1
= (() .) . () . () (,,)
但说真的,你不应该。保持可读性,这意味着有点无点是好的,但不要做得太多。您可以这样编写示例:
\f1 f2 f3 t -> (,,) (f1 t) (f2 t) (f3 t)
(,)是一个具有3个参数的常用函数,因此使其应用程序无需任何特殊设置。然而,它使用了它的论点3次,所以它会很麻烦,而且可能不值得
哈斯克尔的拉姆达博特说这是(美联社)。liftM2(,)
。享受:)尽管应用程序或一元版本更简单、更短,但一种可能揭示“含义”(以及您正在使用的Haskell类型类别的属性)的方法是使用Control.Arrow
uncurry (uncurry (,,)) . ((f &&& g) &&& h)
不过,pointfull版本更优越
这也暴露出你需要Hask的“卡特尔主义”,但不是Hask的所有“封闭性”
这里有一些关于对方答案的详细说明
在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
因此,使用(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
,然后定义
我喜欢lambdabot使用monad函数的方式。我认为这个答案比我的好得多,我主要是转发lambdabot给出的。特别是,我喜欢控件.Applicative
变体!顺便说一下,不要同时使用quot
和mod
。使用quot
和rem
(或仅使用quotRem
)或使用div
和mod
(或仅使用divMod
)。这些配对都有保证,即quotRem m n=(q,r)
意味着n*q+r=m
(对于divMod
)也是如此。顺便问一下,为什么有两对呢?quotRem
和divMod
在负数上有不同的行为divMod
总是返回一个正的mod
部分,但是quotRem
通常要快一点。
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)
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
Prelude Control.Applicative> :t liftA3 (,,)
liftA3 (,,) :: (Applicative f) => f a -> f b -> f c -> f (a, b, c)
liftA3 (,,) ~ (t->a) -> (t->b) -> (t->c) -> (t->(a,b,c))
liftA3 (,,) f g h t = ((((,,) <$> f) <*> g) <*> h) t
= (((,,) <$> f) <*> g) t (h t)
= (((,,) <$> f) t (g t) (h t)
= (((,,) . f) t (g t) (h t)
= (,,) (f t) (g t) (h t)
= (f t, g t, h t)