尝试用 Haskell 找到 GCD。我的代码哪里出错了?
Trying to find GCD with Haskell. Where is the error in my code?
作为练习,我正在尝试自己编写此代码,但我卡住了,不知道代码中的错误在哪里。
module Hf where
--sumSquaresTo :: Integer -> Integer
--sumSquaresTo x = sum [ n^2 | n <- [1..x] ]
divides a b = b `mod` a == 0
divisors a = [n | n <- [1..a], n `divides` a ]
lnko :: Integer -> Integer -> Integer
lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
GHCI 输出:
error:
* Couldn't match expected type `Integer'
with actual type `[a0 -> a0]'
* In the expression:
[n | n <- [1 .. max (a b)], (n `divides` a) && (n `divides` b)]
In an equation for `lnko':
lnko a b
= [n | n <- [1 .. max (a b)], (n `divides` a) && (n `divides` b)]
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error:
* Couldn't match expected type `Integer -> a0'
with actual type `Integer'
* The function `a' is applied to one argument,
but its type `Integer' has none
In the first argument of `max', namely `(a b)'
In the expression: max (a b)
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^^^
error:
* Couldn't match expected type `a0 -> a0'
with actual type `Integer'
* In the second argument of `divides', namely `a'
In the first argument of `(&&)', namely `(n `divides` a)'
In the expression: (n `divides` a) && (n `divides` b)
* Relevant bindings include
n :: a0 -> a0
(bound at C:\Users\erdos\Desktop\haskell\hazi1.hs:12:17)
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^
error:
* Couldn't match expected type `a0 -> a0'
with actual type `Integer'
* In the second argument of `divides', namely `b'
In the second argument of `(&&)', namely `(n `divides` b)'
In the expression: (n `divides` a) && (n `divides` b)
* Relevant bindings include
n :: a0 -> a0
(bound at C:\Users\erdos\Desktop\haskell\hazi1.hs:12:17)
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^
Failed, no modules loaded.
嗯,有2个错误。
在Haskell中,你不写max(a b)
,只是写max a b
。这叫做currying.
您的函数实际上定位了 所有 个公因数。例如:
λ lnko 8 16
[1,2,4,8]
如果您相应地修改类型签名,它将起作用。或者您可能 select 某种因素之一。
总的来说,这是很棒的代码。继续!
类型不匹配。事实上,在你的函数中:
lnko :: Integer -> Integer -> Integer
lnko a b = <b>[</b>n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) <b>]</b>
你在这里 return 一个列表,因为你使用列表理解。此外,您还犯了一些语法错误。例如 max (a b)
表示您以 a
作为函数,以 b
作为参数执行函数应用程序。这应该是 max a b
.
您可以将其重写为:
lnko :: Integer -> Integer -> Integer
lnko a b = <b>maximum</b> [n | n <- [1..<b>min a b</b>], n `divides` a, n `divides` b ]
但是,尽管如此,您在这里使用了一种方法,您可以遍历所有可能的分隔符以找到最大的分隔符。例如,您可以使用通常优于线性搜索的 Euclidean algorithm [wiki]:
lnko :: Integral i => i -> i -> i
lnko a 0 = a
lnko a b = lnko b (mod a b)
这也会更安全,例如,如果您在参数中使用负数。
作为练习,我正在尝试自己编写此代码,但我卡住了,不知道代码中的错误在哪里。
module Hf where
--sumSquaresTo :: Integer -> Integer
--sumSquaresTo x = sum [ n^2 | n <- [1..x] ]
divides a b = b `mod` a == 0
divisors a = [n | n <- [1..a], n `divides` a ]
lnko :: Integer -> Integer -> Integer
lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
GHCI 输出:
error:
* Couldn't match expected type `Integer'
with actual type `[a0 -> a0]'
* In the expression:
[n | n <- [1 .. max (a b)], (n `divides` a) && (n `divides` b)]
In an equation for `lnko':
lnko a b
= [n | n <- [1 .. max (a b)], (n `divides` a) && (n `divides` b)]
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error:
* Couldn't match expected type `Integer -> a0'
with actual type `Integer'
* The function `a' is applied to one argument,
but its type `Integer' has none
In the first argument of `max', namely `(a b)'
In the expression: max (a b)
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^^^
error:
* Couldn't match expected type `a0 -> a0'
with actual type `Integer'
* In the second argument of `divides', namely `a'
In the first argument of `(&&)', namely `(n `divides` a)'
In the expression: (n `divides` a) && (n `divides` b)
* Relevant bindings include
n :: a0 -> a0
(bound at C:\Users\erdos\Desktop\haskell\hazi1.hs:12:17)
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^
error:
* Couldn't match expected type `a0 -> a0'
with actual type `Integer'
* In the second argument of `divides', namely `b'
In the second argument of `(&&)', namely `(n `divides` b)'
In the expression: (n `divides` a) && (n `divides` b)
* Relevant bindings include
n :: a0 -> a0
(bound at C:\Users\erdos\Desktop\haskell\hazi1.hs:12:17)
|
12 | lnko a b = [n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) ]
| ^
Failed, no modules loaded.
嗯,有2个错误。
在Haskell中,你不写
max(a b)
,只是写max a b
。这叫做currying.您的函数实际上定位了 所有 个公因数。例如:
λ lnko 8 16 [1,2,4,8]
如果您相应地修改类型签名,它将起作用。或者您可能 select 某种因素之一。
总的来说,这是很棒的代码。继续!
类型不匹配。事实上,在你的函数中:
lnko :: Integer -> Integer -> Integer
lnko a b = <b>[</b>n | n <- [1..max(a b)], (n `divides` a) && (n `divides` b) <b>]</b>
你在这里 return 一个列表,因为你使用列表理解。此外,您还犯了一些语法错误。例如 max (a b)
表示您以 a
作为函数,以 b
作为参数执行函数应用程序。这应该是 max a b
.
您可以将其重写为:
lnko :: Integer -> Integer -> Integer
lnko a b = <b>maximum</b> [n | n <- [1..<b>min a b</b>], n `divides` a, n `divides` b ]
但是,尽管如此,您在这里使用了一种方法,您可以遍历所有可能的分隔符以找到最大的分隔符。例如,您可以使用通常优于线性搜索的 Euclidean algorithm [wiki]:
lnko :: Integral i => i -> i -> i
lnko a 0 = a
lnko a b = lnko b (mod a b)
这也会更安全,例如,如果您在参数中使用负数。