利用函数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