Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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 - Fatal编程技术网

Haskell 关于何时写作,何时使用的困惑$

Haskell 关于何时写作,何时使用的困惑$,haskell,Haskell,给定上述函数,我不明白为什么let x=sumOfSquares。returnGreatest2返回 returnGreater :: (Ord a) => a -> a -> a returnGreater a b | (a > b) = a | otherwise = b returnGreatest2 :: (Ord a, Num a) => a -> a -> a -> (a, a) returnGreatest2 a b c

给定上述函数,我不明白为什么
let x=sumOfSquares。returnGreatest2
返回

returnGreater :: (Ord a) => a -> a -> a
returnGreater a b
  | (a > b) = a
  | otherwise = b

returnGreatest2 :: (Ord a, Num a) => a -> a -> a -> (a, a)
returnGreatest2 a b c
  | (a > b) = (a, returnGreater b c)
  | otherwise = (b, returnGreater a c)

sumOfSquares :: (Num a) => (a, a) -> a
sumOfSquares (a, b) = a^2 + b^2
:13:24:错误:
•无法将类型“a->a->(a,a)”与“c,c”匹配
预期类型:a->(c,c)
实际类型:a->a->a->(a,a)
•可能原因:“returnGreatest2”应用于太少的参数
在“(.”的第二个参数中,即“returnGreatest2”
在表达式中:sumOfSquares。返回最大值2
在“x”的方程式中:x=平方和。返回最大值2
•相关绑定包括
x::a->c(绑定时间:13:5)

但是
sumOfSquares$returngreatest23557
做了正确的事情。由于
returnGreatest2
生成的类型与
sumOfSquares
期望的类型相同,因此我认为我可以将它们组合起来。

组合和咖喱可能会有点混淆<代码>平方米。returnGreatest2与
\x->sumOfSquares(returnGreatest2 x)
相同,但是
returnGreatest2 x
的类型是
(Ord a,Num a)=>a->a->(a,a)
。您需要传递所有预期参数,然后才能最终获得类型为
(Ord a,Num a)=>(a,a)
的值,该值可被
sumOfSquares
接受

另一方面,
sumOfSquares$returnGreatest2 3 5 7
的解析与
sumOfSquares$(returnGreatest2 3 5 7)
相同;
($)
运算符的优先级低于函数应用程序(或任何其他运算符)

要真正组合这两个函数,需要几个层次的组合:

<interactive>:13:24: error:
    • Couldn't match type ‘a -> a -> (a, a)’ with ‘(c, c)’
      Expected type: a -> (c, c)
        Actual type: a -> a -> a -> (a, a)
    • Probable cause: ‘returnGreatest2’ is applied to too few arguments
      In the second argument of ‘(.)’, namely ‘returnGreatest2’
      In the expression: sumOfSquares . returnGreatest2
      In an equation for ‘x’: x = sumOfSquares . returnGreatest2
    • Relevant bindings include
        x :: a -> c (bound at <interactive>:13:5)
()
函数的两边都应该是一个单参数函数,因此它将
returnGreatest2
视为
a->(a->a->(a,a))
。但是
sumOfSquares
不接受
(a->a->(a,a))
作为参数。一种方法是像以前一样使用
$
,并应用所有参数,但也可以显式声明前两个参数:

let f = ((sumOfSquares .) . ) . returnGreatest2
这样,类型将匹配。

您可以尝试此方法

let x a b = sumOfSquares . returnGreatest2 a b
x :: (Num c, Ord c) => c -> c -> c -> c
$
具有最低优先级
returnGreatest2 3 5
是部分应用于
3
5
的函数
returnGreatest2
,因此仍然是一个接受单个变量的函数。现在有两个函数接受一个变量:

  • sumOfSquares
  • returngreatest25

您可以使用
组合它们,这就是
的目的:使用单个变量输入和单个变量输出组合函数

我给你一个提示。合成运算符的类型是什么?请记住
(::(b->c)->(a->b)->a->c的类型。但是
returnGreatest2
需要4个参数,因此它应该应用3个参数(直到它的类型变成
a->(a,a)
或者像上面的类型签名
(a->b)
然后才能将其应用于复合运算符。例如
让x=sumOfSquares.return2 3 5
,然后
x7
将给出结果。下面是如何将多个参数的复合形式转换为无点形式的简短推导。
\x y z->g((f x y)z)
=(合成的定义)=
\x y->g.f x y
=(在前缀中重写)=
\x y->(.g)(.f x)y
=(合成的定义)=
\x->(.g.f x
=(在前缀中重写)=
\x->(.g)(.g))(fx)
=(合成的定义)=
(.g.).f
=(.code>实例函子(.a)
)=
fmap(fmap g).f
。此处
g
=
sumOfSquares
f
=
returnGreatest2
。通常,要用n参数函数组成一个单参数函数,需要
fmap
n− 1次。我更喜欢将无点版本写成
fmap(fmap-sumOfSquares)。returnGreatest2
fmap
与这里的
()
相同(在
(>)\uu
functor中),但imo更清楚:每个
fmap
“映射”一个参数。为了清晰起见,包括额外的括号,
fmap(fmap-sumOfSquares)
专门用于类型
(a->a->(a,a))->(a->a->a)
,使其可与
returnGreatest2::a->(a->a->(a,a))
组合。
sumOfSquares . returnGreatest2 3 5 $ 7