为什么这个点自由定义在 Haskell 中不起作用?
Why does this point free definition not work in Haskell?
我试着做了以下函数定义:
relativelyPrime x y = gcd x y == 1
免分:
relativelyPrime = (== 1) . gcd
但是,这给了我以下错误:
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
不太明白。 gcd
接受两个 Ints/Integer,returns 一个 Ints/Integer,然后检查那个 Int/Integer 是否等于“1”。我看不出我的错误在哪里。
正如您评论的那样 - 如果您真的想要一个无点版本,您可以先使用 uncurry gcd
将 gcd
转换为接受单个输入(元组)的版本:
Prelude> :t uncurry gcd
uncurry gcd :: Integral c => (c, c) -> c
然后用 (== 1)
检查,最后 curry
再次检查原始签名:
relativeelyPrime = curry ((== 1) . (uncurry gcd))
你的版本不起作用只是因为 gcd
如果只给定第一个参数就产生一个函数,这对于等待数字的 (== 1)
来说不是合法的输入。
它不起作用,因为 gcd
需要两个输入,而函数组合只提供 gcd
一个输入。考虑函数组合的定义:
f . g = \x -> f (g x)
因此,表达式 (== 1) . gcd
等价于:
\x -> (== 1) (gcd x)
这不是你想要的。你想要:
\x y -> (== 1) (gcd x y)
您可以定义一个新的运算符来组合一个一元函数和一个二元函数:
f .: g = \x y -> f (g x y)
那么,你的表情就变成了:
relativelyPrime = (== 1) .: gcd
其实(.:)
运算符可以按照函数组合来定义:
(.:) = (.) . (.)
看起来有点像owl,但它们确实是等价的。因此,表达式的另一种写法:
relativelyPrime = ((== 1) .) . gcd
如果您想了解发生了什么,请参阅:What does (f .) . g mean in Haskell?
我试着做了以下函数定义:
relativelyPrime x y = gcd x y == 1
免分:
relativelyPrime = (== 1) . gcd
但是,这给了我以下错误:
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
不太明白。 gcd
接受两个 Ints/Integer,returns 一个 Ints/Integer,然后检查那个 Int/Integer 是否等于“1”。我看不出我的错误在哪里。
正如您评论的那样 - 如果您真的想要一个无点版本,您可以先使用 uncurry gcd
将 gcd
转换为接受单个输入(元组)的版本:
Prelude> :t uncurry gcd
uncurry gcd :: Integral c => (c, c) -> c
然后用 (== 1)
检查,最后 curry
再次检查原始签名:
relativeelyPrime = curry ((== 1) . (uncurry gcd))
你的版本不起作用只是因为 gcd
如果只给定第一个参数就产生一个函数,这对于等待数字的 (== 1)
来说不是合法的输入。
它不起作用,因为 gcd
需要两个输入,而函数组合只提供 gcd
一个输入。考虑函数组合的定义:
f . g = \x -> f (g x)
因此,表达式 (== 1) . gcd
等价于:
\x -> (== 1) (gcd x)
这不是你想要的。你想要:
\x y -> (== 1) (gcd x y)
您可以定义一个新的运算符来组合一个一元函数和一个二元函数:
f .: g = \x y -> f (g x y)
那么,你的表情就变成了:
relativelyPrime = (== 1) .: gcd
其实(.:)
运算符可以按照函数组合来定义:
(.:) = (.) . (.)
看起来有点像owl,但它们确实是等价的。因此,表达式的另一种写法:
relativelyPrime = ((== 1) .) . gcd
如果您想了解发生了什么,请参阅:What does (f .) . g mean in Haskell?