[英]How to write the type declaration of an Haskell function with no arguments?
[英]How do I write a type declaration for this function?
我对Haskell还是很陌生,我遇到了一个问题,可能不应该太难解决,但却让我很沮丧。
我写了一个函数:
maxFor l n = n * m * (m + 1) / 2 where m = l `div` n
该函数属于一个很小的模块,该模块加载时没有问题,但是每次在加载模块后尝试使用该函数时,都会抛出两个令我感到尴尬的错误:
<interactive>:182:1:
No instance for (Integral a0) arising from a use of `maxFor'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Integral Int -- Defined in `GHC.Real'
instance Integral Integer -- Defined in `GHC.Real'
instance Integral GHC.Types.Word -- Defined in `GHC.Real'
In the expression: maxFor 999 5
In an equation for `it': it = maxFor 999 5
<interactive>:182:8:
No instance for (Num a0) arising from the literal `999'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Num Double -- Defined in `GHC.Float'
instance Num Float -- Defined in `GHC.Float'
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus three others
In the first argument of `maxFor', namely `999'
In the expression: maxFor 999 5
In an equation for `it': it = maxFor 999 5
我知道这是在告诉我我的函数缺少正确的类型声明,但是我不理解如何在不再次编译器na的情况下编写它。 我尝试了无数种变体,但我不了解实际问题并不能帮助我解决问题。
问题的一部分可能是我在一个函数中使用了(/)
和div
,因此所需的类型声明可能会包含Fractional
和/或Integral
,因为:
(/) :: Fractional a => a -> a -> a
和:
div :: Integral a => a -> a -> a
但这是我所能做到的,我被困住了。 我将如何为maxFor
编写类型声明? 我究竟做错了什么? 我是否缺少或忽略了明显的东西?
任何帮助和建设性的反馈将不胜感激。
编辑:我已经在堆栈溢出上找到了这个答案,这已经有所帮助。 我仍然很感谢您的帮助,但是,如果事实证明我是个白痴并且最终被人们低估了,我当然会删除这个问题。
注意:这篇文章是用识字的Haskell撰写的。 您可以将其另存为Max.lhs并在GHCi中尝试。
首先,让您使用(/2)
。 数n * m * (m + 1)
奇数还是偶数? 好吧,或者m
为奇数, m + 1
为偶数,因此整个乘积为偶数,或者m
为偶数,并且相同的参数成立。
因此,我们可以使用n * m * (m + 1) `div` 2
代替n * m * (m + 1) / 2
n * m * (m + 1) `div` 2
:
> maxFor l n = n * m * (m + 1) `div` 2
> where m = l `div` n
现在,我们要做的就是检查我们使用的函数的类型:
(+) :: Num a => a -> a -> a
(*) :: Num a => a -> a -> a
div :: Integral n => n -> n -> n
这直接导致您输入:
> maxFor :: Integral n => n -> n -> n
另外,您可以使用某些特定类型来排除错误:
maxFor :: Integer -> Integer -> Integer
-- Now GHC yells at you since Integer doesn't have a Fractional instance
-- and you try to use (/).
您已经认识到问题所在。 div
表示l
和n
是某些整数类型,但(/)
表示它们是分数。 在您通常的Prelude
,没有数据类型是两个类型类的实例。 您可以在GHCi中进行检查:
Prelude> :info Fractional
class Num a => Fractional a where
(/) :: a -> a -> a
recip :: a -> a
fromRational :: Rational -> a
-- Defined in ‘GHC.Real’
instance Fractional Float -- Defined in ‘GHC.Float’
instance Fractional Double -- Defined in ‘GHC.Float’
Prelude> :info Integral
class (Real a, Enum a) => Integral a where
quot :: a -> a -> a
rem :: a -> a -> a
div :: a -> a -> a
mod :: a -> a -> a
quotRem :: a -> a -> (a, a)
divMod :: a -> a -> (a, a)
toInteger :: a -> Integer
-- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
这是第一部分。
第二部分来自文字。 999
或5
类型为Num a => a
。 现在,GHC处于困境和困境之间:它必须找到一个Num
实例,它既是Integral
也是Fractional
。 由于没有这样的类型(请参见上文),GHC由于模棱两可而放弃了。 您也可以在GHCi中进行检查:
Prelude> 5 :: Num a => a
5
Prelude> 5 :: (Fractional a, Integral a) => a
<interactive>:7:1:
No instance for (Fractional a0) arising from a use of ‘it’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Integral a => Fractional (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance Fractional Double -- Defined in ‘GHC.Float’
instance Fractional Float -- Defined in ‘GHC.Float’
In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
因此,这主要是导致出现错误的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.