Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell-以奇怪的方式组合三个函数_Haskell_Composition - Fatal编程技术网

Haskell-以奇怪的方式组合三个函数

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) (

我有三个函数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) (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