我正在尝试定义一个函数来找到两个数字的绝对差值,这两个都是
absoluteDifference 2 5
absoluteDifference 5 2
返回3
。
到目前为止,这是我的最大努力:
absoluteDifference :: Num a => a -> a -> a
absoluteDifference = abs . (-)
在我看来,这会将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
但我想知道如何撰写这些功能。
答案 0 :(得分:4)
(.)
Prelude> :i (.)
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in ‘GHC.Base’
表明它接受类型为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
注意:正如用户@ david-young指出的那样,of'
通过指定类型可以更加通用:
of' :: (a -> b) -> (c -> d -> a) -> c -> d -> b
of' f g x y = f (g x y)
答案 1 :(得分:3)
除了Haleemur Ali's answer所建议的定义自定义运算符之外,还有一种方法是通过将单参数函数作为(.)
的第二个参数来使定义更少无点。
absoluteDifference a = abs . (-) a
考虑到函数中两个参数的作用有多么相似,从可读性的角度来看,以这种方式编写它并没有多大意义(尽管在其他情况下可能效果更好)。 / p>
另一种可能性是使它更加无点(通过将函数修改函数作为(-)
的第一个参数):
absoluteDifference = (abs .) . (-)
虽然这是一个不错的客厅技巧,但这种带有(.)
部分的代码相当神秘,通常最好避免它在真实的#34;代码。
答案 2 :(得分:1)
为什么不是猫头鹰操作员?
function zoomIn(i) {
return new Promise(res => {
setTimeout(()=>res(i), 1000);
});
};
function anotherPromise() {
return Rx.Observable.defer(()=> {
return new Promise(res => {
setTimeout(()=>res('anotherPromise'), 3000);
});
});
}
const zoonInList = Array(5).fill(0).map((x, i)=>i).map(i=>
Rx.Observable.defer(()=> {
return zoomIn(i);
})
);
Rx.Observable.concat(...zoonInList, anotherPromise())
.subscribe(x=>console.log(x))
答案 3 :(得分:1)
其实你的答案非常接近。您所需要的只是修改如下;
absDiff :: Num a => a -> a -> a
absDiff n = abs . (n-)
*Main> absDiff 3 9
6
*Main> absDiff 9 3
6