我现在正试图解决Project Euler的第9个问题,但是Haskell不会停止向我大吼大叫关于不匹配的类型 . 问题是,ghci告诉我它期望的类型与函数类型定义中给出的类型不同 .
这是代码:
solvePyth :: Int -> Int -> Float
solvePyth x y
|valid = x * y * z
|otherwise = if y < x then solvePyth x (y + 1) else solvePyth (x + 1) 1
where z = sqrt $ fromIntegral $ x^2 + y^2
valid = (x^2 + y^2 == z^2) && (x + y + z == 1000)
这是我得到的错误:
Prelude> :l debug
[1 of 1] Compiling Main ( debug.hs, interpreted )
debug.hs:3:14:
Couldn't match expected type `Float' with actual type `Int'
In the first argument of `(*)', namely `x'
In the first argument of `(*)', namely `x * y'
debug.hs:3:18:
Couldn't match expected type `Float' with actual type `Int'
In the second argument of `(*)', namely `y'
In the first argument of `(*)', namely `x * y'
debug.hs:6:33:
Couldn't match expected type `Int' with actual type `Float'
In the first argument of `(^)', namely `z'
In the second argument of `(==)', namely `z ^ 2'
Failed, modules loaded: none.
我不明白为什么 (*)
和 (^)
期待Floats和Ints,当检查他们用 :t
输入ghci时,他们的争论只需要被认为是Nums .
1 回答
以下是修复输入问题的一种方法:
(*)
和(^)
将适用于一般安装在Num
类中的参数,但重要的是类型必须相同 . 以下是(*)
的类型定义:但请注意
a
必须是同一类型,所以如果你部分地应用Int
:它期望第二个参数和输出也是
Int
.另一方面
(^)
的类型:在两个可能不同类型的参数上工作,所以如果我们部分应用
Int
它将产生Int
,但第二个参数仍然可以是任意Integral
:基本上每当你看到
a -> a -> a
时,这意味着类型变量a
最终必须是同一类型,这就是为什么你不能将Int
和Float
与(*)
混合,尽管它们都安装在Num
中 .