Haskell-以奇怪的方式组合三个函数
我有三个函数xyz和一个函数functionComposer 我希望functionComposer将函数xyz作为参数,并返回一个函数,该函数使用y和z的结果作为参数输入x并应用x 在数学记数法中:Haskell-以奇怪的方式组合三个函数,haskell,composition,Haskell,Composition,我有三个函数xyz和一个函数functionComposer 我希望functionComposer将函数xyz作为参数,并返回一个函数,该函数使用y和z的结果作为参数输入x并应用x 在数学记数法中:x(y(a),z(b)) 我没有要求这样做:functionComposer x y z=x.y.z 例如: double x = x + x summer x y = x + y functionComposer summer double double = summer (double) (
x(y(a),z(b))
我没有要求这样做:functionComposer x y z=x.y.z
例如:
double x = x + x
summer x y = x + y
functionComposer summer double double = summer (double) (double)
如果x=2,使用您的符号,结果应为8(2+2)+(2+2):
functionComposer summer double1 double2 = \x -> summer (double1 x) (double2 x)
\x->…
表示将x
映射到…
的函数
注意:我必须为
double
函数参数指定不同的名称,因为通常您需要组合不同的函数。您也可以像这样使用(>)a的应用程序实例
import Control.Applicative
funcComp summer double1 double2 = summer <$> double1 <*> double2
理解这一点的方法是,对于(>)a
,applicative和monad实例都意味着对double1
和double2
都接受的函数值进行“参数化”。我不知怎么地感觉,您似乎想要一系列令人困惑的点,因此:
functionComposer :: (c -> d -> e) -> (a -> c) -> (b -> d) -> a -> b -> e
functionComposer x y z = (. z) . (x . y)
这是“自然”产生的
functionComposer x y z a = (x . y) a . z
但为什么要到此为止
functionComposer x y = (. (x . y)) . flip (.)
不,还有:
functionComposer x = (. flip (.)) . flip (.) . (x .)
更多
您基本上是在并行1中评估y
和z
。表达这一点的最基本的组合词是。结果是您希望将其馈送到x
,因此基本上您希望编写
x . (y***z) -- or x <<< y***z
1Mind,我不是指多线程意义上的并行,只是“语义上的并行”。你的描述令人困惑;你最初说你有x和y作为函数,a和b作为参数,但最后你谈到了一个叫做x的参数。你可以写你已经写过的东西,haskell会接受它:\x y z a b->x(y(a),z(b))
。或者没有元组和附加括号:\x y z a b->x(y a)(z b)
问题是,如果函数y或z需要多个参数,该函数将无法工作。我说我得到它只是为了友善。但老实说,这里的解决方案只是局部的。仅当y和z的类型为y::a->c z::b->d时,它才起作用。例如,我在寻找一个通用的解决方案。如果我定义一个函数:composer f1 f2 f3=f1.f2.f3 f3的类型不是必需的a->b,它可以有多个参数,可以是a->b->c->d或其他任何类型。可爱的应用程序。嗯。所以,基本上,funcomp=liftA2
。这不是OP想要的。我一直在寻找这样的东西。关键是你限制了y和z的参数。我不想定义y和z的类型。我希望它们是我们一无所知的generinc函数。如果我们定义function composer而不定义其类型,haskell应该能够推断x y z的类型(我相信…),这将使函数更有用,例如,本作业的前一点是编写一个类似于composingMachine1 x y z=x.y.z的函数,函数类型为composingMachine::t1->t2->(t1->t2->t)->t@user3630355,所有的答案都是通用的。对不起,如果我非常不懂,但是,在本例中,functionComposer x y z=(.z)。(x.y)函数正在处理y,结果进入x,结果进入z,对吗?如果您能一步一步地解释,我将不胜感激。这本身就有点难以解释,因此让我们从functionComposer x y z a b=x(y a)(z b)
的完整扩展开始。可以在z
上转换为x(y a)
,因此functionComposer x y z a=x(y a)。z
x(ya)
也可以写(x.y)a
,因此它是函数生成器xyza=(x.y)a。z
。可以写入()((x.y)a)z
,可以写入翻转(.z)((x.y)a)
,然后可以以与翻转(.z.)相同的方式取出a
。(x.y)
flip(.z
是(.z)
,所以整个过程都以(.z)结束。(x.y)
。
functionComposer = (((. flip (.)) . flip (.)) .) . (.)
x . (y***z) -- or x <<< y***z
functionComposer :: (c -> d -> e) -> (a -> c) -> (b -> d) -> a -> b -> e
functionComposer x y z = curry $ uncurry x <<< y *** z