我试着做出以下函数定义:
relativelyPrime x y = gcd x y == 1
Run Code Online (Sandbox Code Playgroud)
点免费:
relativelyPrime = (== 1) . gcd
Run Code Online (Sandbox Code Playgroud)
但是,这给了我以下错误:
Couldn't match type ‘Bool’ with ‘a -> Bool’
Expected type: (a -> a) -> a -> Bool
Actual type: (a -> a) -> Bool
Relevant bindings include
relativelyPrime :: a -> a -> Bool (bound at 1.hs:20:1)
In the first argument of ‘(.)’, namely ‘(== 1)’
In the expression: (== 1) . gcd
In an equation for ‘relativelyPrime’:
relativelyPrime = (== 1) . gcd
Run Code Online (Sandbox Code Playgroud)
我不太明白.gcd取两个Ints/Integer,返回一个Ints/Integer,然后检查一个Int/Integer是否等于'1'.我没看到我的错误在哪里.
它不起作用,因为gcd需要两个输入,而功能组合只提供gcd一个输入.考虑功能组成的定义:
f . g = \x -> f (g x)
Run Code Online (Sandbox Code Playgroud)
因此,表达式(== 1) . gcd相当于:
\x -> (== 1) (gcd x)
Run Code Online (Sandbox Code Playgroud)
这不是你想要的.你要:
\x y -> (== 1) (gcd x y)
Run Code Online (Sandbox Code Playgroud)
您可以定义一个新运算符来组成具有二元函数的一元函数:
f .: g = \x y -> f (g x y)
Run Code Online (Sandbox Code Playgroud)
然后,你的表达式变为:
relativelyPrime = (== 1) .: gcd
Run Code Online (Sandbox Code Playgroud)
实际上,(.:)运算符可以根据函数组成来定义:
(.:) = (.) . (.)
Run Code Online (Sandbox Code Playgroud)
它看起来有点像猫头鹰,但它们确实相当.因此,编写表达式的另一种方法是:
relativelyPrime = ((== 1) .) . gcd
Run Code Online (Sandbox Code Playgroud)
如果你想了解发生了什么,那么请看:(f.).在Haskell中意味着什么?
当你评论它时 - 如果你真的想要一个无点版本,你可以先用它uncurry gcd来转换gcd成一个接受单个输入(一个元组)的版本:
Prelude> :t uncurry gcd
uncurry gcd :: Integral c => (c, c) -> c
Run Code Online (Sandbox Code Playgroud)
然后检查,(== 1)最后curry再次检查原始签名:
relativeelyPrime = curry ((== 1) . (uncurry gcd))
Run Code Online (Sandbox Code Playgroud)
你的版本不起作用只是因为gcd如果只给出第一个参数就产生一个函数,这不是(== 1)等待数字的合法输入.
| 归档时间: |
|
| 查看次数: |
144 次 |
| 最近记录: |