Haskell,在函数内乘以Int和float [英] Haskell, multiplying Int and Float within a function
问题描述
为什么在ghci中我可以输入:
5.0 *(3 - 1)
> 10.0
但是,如果我尝试在.hs文件中创建一个函数并将其加载:
test :: Float - > Int - > Int - > Float
test abc = a *(b - c)
? 难以匹配预期类型'浮点数'与推断类型'Int'?
我该如何编写一个函数,它接受一个浮点数和2个整数参数,并对它们执行上述操作?
我使用的是ghci v6.12.1,如果这样做有区别...
数字文字(即在Haskell代码中只输入一个数字)并不是固定类型,它们是多态的,需要在需要它们的具体类型中进行评估。
因此,表达式 5.0 *(3 - 1)
不是乘以 Int
by Float
。 5.0
必须是小数
类型, 3
和 1
均为 Num
类型。 3 - 1
表示3和1必须是相同 Num
类型,但是我们仍然没有(更多)约束它是哪一个特定的结果
*
表示两个参数必须是相同的类型,结果也将是相同的类型。由于 5.0
是一些小数类型,所以
(3-1)
一定也是。我们已经知道 3
, 1
和(3-1)
必须是 Num
类型,但所有小数
类型也是 Num
类型,所以这个需求是不冲突的。
最终结果是整个表达式 5.0 *(3-1 )
是某种类型,它是小数
, 5.0
, 3
和 1
都是相同的类型。您可以在GHCi中使用:t
命令来查看:
前奏> :t 5.0 *(3-1)
5.0 *(3-1)::小数a => a
但是为了实际评估该表达式,我们需要这样做一些具体类型。如果我们正在对此进行评估并将其传递给需要 Float
, Double
或某些其他特定<$ c的函数$ c> Fractional 类型,那么Haskell会挑选那个。如果我们只是在没有其他上下文的情况下评估表达式,Haskell会有一些默认规则为您自动选择一个(如果默认规则不适用,它会给您一个关于不明确类型变量的类型错误)。
Prelude> 5.0 *(3 - 1)
10.0
Prelude> :t it
it :: Double
以上我评估过 5.0 *(3 - 1)
,然后询问变量GHCi总是绑定到它所评估的最后一个值的魔术 it
变量的类型。这告诉我,GHCi默认了我的小数a =>为了计算表达式的值是
类型只是 10.0
,一个 Double
>。在做这样的评估时,它只是多次(并减去) Double
s,它从来没有乘以 Double
code> Int 。
现在,当您尝试多个数字文字,看起来像它们可能是不同的类型。但是你的 其他语言只有在某些情况下隐式地将调用插入转换函数才支持这种操作。 Haskell 从不在类型之间隐式转换,但它具有转换功能。如果你想让它们被调用,你只需要明确地调用它们。这将做到这一点: Why is it that in ghci I can enter: But if I try and create a function in a .hs file and load it in: I am hit with an error? "Couldnt match expected type 'Float' against inferred type 'Int'?
And how can I write a function that takes in one floating point and 2 integer arguments and performs the above operation on them? I am using ghci v6.12.1 if that makes a difference... Numeric literals (i.e. just typing a number in Haskell code) are not some fixed type. They are polymorphic. They need to be evaluated in some context that requires them to have a concrete type. So the expression The The end result is that the whole expression But to actually evaluate that expression, we need to do so for some concrete type. If we were evaluating this and passing it to some function that required Above I've evaluated Now, that's what's going on when you attempt to multiple numeric literals that look like they might be of different types. But your Other languages support this sort of operation only by implicitly inserting calls to conversion functions under some circumstances. Haskell never implicitly converts between types, but it has the conversion functions. You just need to call them explicitly if you want them to be called. This would do the trick:
这篇关于Haskell,在函数内乘以Int和float的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! test
函数不是乘以文字,而是乘以特定已知类型的变量。在Haskell中,不能将 Int
乘以 Float
,因为 *
运算符的类型为 Num a => a - > a - >一个
- 它采用相同数值类型的两个值,并为您提供该类型的结果。你可以用 Int
乘以一个 Int
得到一个 Int
或 Float
由 Float
得到 Float
。你不能用 Float
乘以 Int
得到 ??? < code。。
test :: Float - > Int - > Int - > Float
test a b c = a * fromIntegral(b - c)
5.0 * (3 - 1)
> 10.0
test :: Float -> Int -> Int -> Float
test a b c = a * (b - c)
5.0 * (3 - 1)
is not multiplying an Int
by a Float
. 5.0
has to be some Fractional
type, 3
and 1
are each some Num
type. 3 - 1
means that the 3 and the 1 both have to be the same Num
type, but we still don't (yet) have any more constraints about which particular one it is; the result of the subtraction is the same type.*
means both arguments have to be the same type, and the result will be the same type too. Since 5.0
is some Fractional
type, the (3 - 1)
must be too. We already knew that 3
, 1
, and (3 - 1)
had to be some Num
type but all Fractional
types are also Num
types, so this requirements are not in conflict.5.0 * (3 - 1)
is some type that is Fractional
, and the 5.0
, 3
, and 1
are all the same type. You can use the :t
command in GHCi to see this:Prelude> :t 5.0 * (3 - 1)
5.0 * (3 - 1) :: Fractional a => a
Float
, Double
, or some other particular Fractional
type then Haskell would pick that one. If we just evaluate the expression with no other context requiring it to be a particular type, Haskell has some defaulting rules to automatically choose one for you (if the defaulting rules don't apply it will instead give you a type error about ambiguous type variables).Prelude> 5.0 * (3 - 1)
10.0
Prelude> :t it
it :: Double
5.0 * (3 - 1)
, then asked for the type of the magic it
variable which GHCi always binds to the last value it evaluated. This tells me that GHCi has defaulted my Fractional a => a
type to just Double
, in order to compute that the value of the expression was 10.0
. In doing that evaluation, it only ever multipled (and subtracted) Double
s, it never multiplied a Double
by an Int
.
test
function isn't multiplying literals, it's multiplying variables of particular known types. In Haskell you can't multiply an Int
by a Float
because the *
operator has type Num a => a -> a -> a
- it takes two values of the same numeric type and gives you a result that is that type. You can multiply an Int
by an Int
to get an Int
, or a Float
by a Float
to get a Float
. You can't multiply an Int
by a Float
to get a ???
.test :: Float -> Int -> Int -> Float
test a b c = a * fromIntegral (b - c)