List Haskell中的长度函数和类型类
这是一个工作函数,它遍历一个数字列表,并将每个元素与以下元素相加List Haskell中的长度函数和类型类,list,haskell,List,Haskell,这是一个工作函数,它遍历一个数字列表,并将每个元素与以下元素相加 media :: (Num a) => [a] -> a media [] = 0 media lst = (head lst) + media (tail lst) 第二个函数应该得到这个和,然后除以列表的长度,从而得到列表的算术平均值。但是编译器返回给我这个 media2 :: (Num a) => [a] -> a media2 str = (media str) / (length str) 我
media :: (Num a) => [a] -> a
media [] = 0
media lst = (head lst) + media (tail lst)
第二个函数应该得到这个和,然后除以列表的长度,从而得到列表的算术平均值。但是编译器返回给我这个
media2 :: (Num a) => [a] -> a
media2 str = (media str) / (length str)
我不明白我做错了什么,有人能告诉我吗?函数总是返回一个Int
,所以你试图用(Num a)=>a
除以Int
。该函数将Int
转换为任何Num
类型:
src/Main.hs@6:29-6:39Could not deduce (a ~ Int)
from the context (Num a)
bound by the type signature for media2 :: Num a => [a] -> a
at /home/app/isolation-runner-work/projects/32614/src.207/Main.hs:6:1-39
`a' is a rigid type variable bound by
the type signature for media2 :: Num a => [a] -> a
at /home/app/isolation-runner-work/projects/32614/src.207/Main.hs:6:1
In the return type of a call of `length'
In the second argument of `(/)', namely `(length str)'
In the expression: (media str) / (length str)
编辑
关于一些有见地的评论,我只想说几句:
media
功能只是前奏曲的sum
整数
平均值,因此我将media2
上的约束更改为分数
,而不是Num
。这是因为/
的类型为(/)::(分数a)=>a->a->a
。或者,您可以使用
media2 :: (Fractional a) => [a] -> a
media2 str = (media str) / (fromIntegral $ length str)
但是你总是会得到一个积分平均值,这可能不是你想要的Int
,因此您试图将(Num a)=>a
除以Int
。该函数将Int
转换为任何Num
类型:
src/Main.hs@6:29-6:39Could not deduce (a ~ Int)
from the context (Num a)
bound by the type signature for media2 :: Num a => [a] -> a
at /home/app/isolation-runner-work/projects/32614/src.207/Main.hs:6:1-39
`a' is a rigid type variable bound by
the type signature for media2 :: Num a => [a] -> a
at /home/app/isolation-runner-work/projects/32614/src.207/Main.hs:6:1
In the return type of a call of `length'
In the second argument of `(/)', namely `(length str)'
In the expression: (media str) / (length str)
编辑
关于一些有见地的评论,我只想说几句:
media
功能只是前奏曲的sum
整数
平均值,因此我将media2
上的约束更改为分数
,而不是Num
。这是因为/
的类型为(/)::(分数a)=>a->a->a
。或者,您可以使用
media2 :: (Fractional a) => [a] -> a
media2 str = (media str) / (fromIntegral $ length str)
但是你总是会得到一个积分平均值,这可能不是你想要的数据。列表
:
genericLength函数是长度的重载版本。特别是,它不返回Int,而是返回作为Num实例的任何类型。但是,它的效率低于length
它的类型签名是
media2 :: (Integral a) => [a] -> a
media2 str = (media str) `div` (fromIntegral $ length str)
用法:
genericLength :: Num i => [a] -> i
您可以使用from数据。列表
:
genericLength函数是长度的重载版本。特别是,它不返回Int,而是返回作为Num实例的任何类型。但是,它的效率低于length
它的类型签名是
media2 :: (Integral a) => [a] -> a
media2 str = (media str) `div` (fromIntegral $ length str)
用法:
genericLength :: Num i => [a] -> i
它说,
media str
有typea
,length str
有typeInt
,你不能用一个除以另一个,因为它不能证明a
实际上是Int
;它叫sum
。它说media str
有typea
,length str
有typeInt
,你不能用一个除以另一个,因为它不能证明a
实际上是Int
。Haskell已经有了一个函数来做media
所做的事情;它被称为sum
。对于来自其他语言的人来说,非直观的一点是/
在Haskell
中处理Int
时不会过载。您必须显式使用整数除法(使用quot
或div
),或将分子和分母转换为实现分数的东西。media2
的类型应为分数a=>[a]->a
Num a
不足。对于来自其他语言的人来说,非直观的一点是/
在Haskell
中处理Int
s时不会过载。您必须显式使用整数除法(使用quot
或div
),或将分子和分母转换为实现分数的东西。media2
的类型应为分数a=>[a]->a
<代码>数值a
不足。