利用函数composition的Haskell绝对差分法

利用函数composition的Haskell绝对差分法,haskell,function-composition,Haskell,Function Composition,我试图定义一个函数来求两个数的绝对差,这样两个数 absoluteDifference 2 5 absoluteDifference 5 2 返回3 以下是我迄今为止所做的最大努力: absoluteDifference :: Num a => a -> a -> a absoluteDifference = abs . (-) 在我的头脑中,这适用于减去两个数字的结果。然而,这给了我一个错误 * Could not deduce (Num (a -> a)) ari

我试图定义一个函数来求两个数的绝对差,这样两个数

absoluteDifference 2 5
absoluteDifference 5 2
返回
3

以下是我迄今为止所做的最大努力:

absoluteDifference :: Num a => a -> a -> a
absoluteDifference = abs . (-)
在我的头脑中,这适用于减去两个数字的结果。然而,这给了我一个错误

* Could not deduce (Num (a -> a)) arising from a use of `abs'
    (maybe you haven't applied a function to enough arguments?)
  from the context: Num a
    bound by the type signature for:
               absoluteDifference :: Num a => a -> a -> a
    at C:\Users\Adam\dev\daily-programmer\e311\e311.hs:3:1-42
* In the first argument of `(.)', namely `abs'
  In the expression: abs . (-)
  In an equation for `absoluteDifference':
      absoluteDifference = abs . (-)
我不明白。我可以简单地实现这个函数

absoluteDifference a b = abs $ a - b
但是我想知道如何组合函数。

有关
(.)的信息。

显示它接受类型为
a->b

但是
(-)
具有

Prelude> :i (-)
class Num a where
  ...
  (-) :: a -> a -> a
  ...
    -- Defined in ‘GHC.Num’
infixl 6 -
因此,可以定义另一个组合运算符,该运算符接受具有上述类型的函数,然后可以组合它们

of' :: (a -> a) -> (a -> a -> a) -> a -> a -> a
of' f g a b = f (g a b)

abdiff = abs `of'` (-)

abdiff 1 10
9
注意:正如user@david young正确指出的那样,“的
可以通过指定以下类型来更一般:

of' :: (a -> b) -> (c -> d -> a) -> c -> d -> b
of' f g x y = f (g x y)

为什么不是猫头鹰操作员

(...) = (.) . (.)
absoluteDifference = abs ... (-)

除了定义自定义运算符(如所建议)外,还有一种替代方法,即使用单个参数函数作为
(.)的第二个参数,从而减少定义的自由点

考虑到函数中两个参数的作用是多么相似,从可读性的角度来看,以这种方式编写它没有多大意义(尽管在其他情况下它可能工作得更好)

另一种可能性是使其更无点(通过将函数修改函数作为
)的第一个参数):


虽然这是一个很好的客厅技巧,但这种带有
(..
部分的代码相当神秘,通常在“真实”代码中避免使用它是一个好主意。

实际上,您的答案非常接近。你所需要的只是修改它如下

absDiff :: Num a => a -> a -> a
absDiff n = abs . (n-)

*Main> absDiff 3 9
6
*Main> absDiff 9 3
6

是的,在这种情况下,我更喜欢使用中缀符号,而不是无点符号。
的类型签名可以更进一步地推广。没错,但是懒洋洋地按1键(即
a
)是非常令人满意的:P.很快更新答案。为什么不使用可变成分?;)
absoluteDifference a = abs . (-) a
absoluteDifference = (abs .) . (-)
absDiff :: Num a => a -> a -> a
absDiff n = abs . (n-)

*Main> absDiff 3 9
6
*Main> absDiff 9 3
6