Function haskell的Int和Num类型

Function haskell的Int和Num类型,function,variables,haskell,types,Function,Variables,Haskell,Types,我有下面的代码来使用args设置一些偏移时间 setOffsetTime :: (Ord a, Num b)=>[a] -> b setOffsetTime [] = 200 setOffsetTime (x:xs) = read x::Int 但编译器说“无法从setOffsetTime的类型签名绑定的上下文(Ord a,Num b)中推断(b~Int):(Ord a,Num b)=>[a]->b 我还发现,如果我想将float作为默认值,我就不能使用200.0。编译器说“不能从

我有下面的代码来使用args设置一些偏移时间

setOffsetTime :: (Ord a, Num b)=>[a] -> b
setOffsetTime [] = 200
setOffsetTime (x:xs) = read x::Int
但编译器说“无法从setOffsetTime的类型签名绑定的上下文(Ord a,Num b)中推断(b~Int):(Ord a,Num b)=>[a]->b

我还发现,如果我想将float作为默认值,我就不能使用200.0。编译器说“不能从文字‘200.0’推导出(分数b)”

有谁能给我看一些代码作为一个函数(不是在前奏曲中),它需要一个参数来存储一些变量,这样我就可以在其他函数中使用了?我可以在main=do中这样做,但希望如此 使用一个优雅的函数来实现这一点。 Hasekll里有什么全局常量的东西吗?我在谷歌上搜索过,但似乎没有


我想用Haskell来替换我的一些python脚本,虽然这并不容易。

如果您确信函数的实现是正确的,即它应该将输入列表中的第一个元素解释为要返回的数字,如果没有这样的参数,则返回
200
,那么您只需要确保t类型签名与该实现匹配(目前它没有匹配)

为此,例如,您可以删除类型签名并要求ghci推断类型:

$ ghci
GHCi, version 7.6.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :{
Prelude| let setOffsetTime []       = 200
Prelude|     setOffsetTime (x : xs) = read x :: Int
Prelude| :}
Prelude> :t setOffsetTime
setOffsetTime :: [String] -> Int
Prelude> :q
Leaving GHCi.

$
事实上

setOffsetTime          :: [String] -> Int
setOffsetTime []       =  200
setOffsetTime (x : xs) =  read x :: Int
汇编得很好

如果您想要一个更一般的类型,您可以从第二个案例中删除属性
::Int

setOffsetTime          :: (Num a, Read a) => [String] -> a
setOffsetTime []       =  200
setOffsetTime (x : xs) =  read x
setOffsetTime          :: [String] -> Float
setOffsetTime []       =  200.0
setOffsetTime (x : xs) =  read x

从您添加到问题的注释中,我了解到您希望函数返回浮点数。在这种情况下,您可以编写

setOffsetTime          :: (Num a, Read a) => [String] -> a
setOffsetTime []       =  200
setOffsetTime (x : xs) =  read x
setOffsetTime          :: [String] -> Float
setOffsetTime []       =  200.0
setOffsetTime (x : xs) =  read x
或者更一般地说:

setOffsetTime          :: (Fractional a, Read a) => [String] -> a
setOffsetTime []       =  200.0
setOffsetTime (x : xs) =  read x

如果您确信函数的实现是正确的,即它应该将其输入列表中的第一个元素解释为要返回的数字,并且如果没有这样的参数,则返回
200
,那么您只需要确保类型签名与该实现相匹配(现在它没有这样做)

为此,例如,您可以删除类型签名并要求ghci推断类型:

$ ghci
GHCi, version 7.6.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :{
Prelude| let setOffsetTime []       = 200
Prelude|     setOffsetTime (x : xs) = read x :: Int
Prelude| :}
Prelude> :t setOffsetTime
setOffsetTime :: [String] -> Int
Prelude> :q
Leaving GHCi.

$
事实上

setOffsetTime          :: [String] -> Int
setOffsetTime []       =  200
setOffsetTime (x : xs) =  read x :: Int
汇编得很好

如果您想要一个更一般的类型,您可以从第二个案例中删除属性
::Int

setOffsetTime          :: (Num a, Read a) => [String] -> a
setOffsetTime []       =  200
setOffsetTime (x : xs) =  read x
setOffsetTime          :: [String] -> Float
setOffsetTime []       =  200.0
setOffsetTime (x : xs) =  read x

从您添加到问题的注释中,我了解到您希望函数返回浮点数。在这种情况下,您可以编写

setOffsetTime          :: (Num a, Read a) => [String] -> a
setOffsetTime []       =  200
setOffsetTime (x : xs) =  read x
setOffsetTime          :: [String] -> Float
setOffsetTime []       =  200.0
setOffsetTime (x : xs) =  read x
或者更一般地说:

setOffsetTime          :: (Fractional a, Read a) => [String] -> a
setOffsetTime []       =  200.0
setOffsetTime (x : xs) =  read x

我认为这种类型的签名并不代表你所认为的那样:

setOffsetTime::(Ord a,Num b)=>[a]->b

它说的是“如果你给我一个
[a]
类型的值,对于任何
a
类型,你选择它是
Ord
类型类的成员,我会给你一个
b
类型的值,对于你选择它是
Num
类型类的成员的任何
b
“。调用方可以选择每次调用
setOffsetTime
时使用的特定类型
a
b

因此,尝试返回类型为
Int
(或
Float
,或任何特定类型)的值是没有意义的
Int
确实是type类
Num
的成员,但它不是type类
Num
的任何成员。根据该类型签名,我应该能够创建一个您从未见过的全新的
Num
实例,从您的模块导入
setOffsetTime
,并调用它以获取我的新类型的值

要获得可接受的返回值,只能使用同样返回任意
Num
的函数。不能使用任何特定具体类型的函数


存在类型本质上是一种机制,允许被调用方选择类型变量的值(然后,无论类型是什么,都必须写入调用方才能工作),但在你还在学习的时候,这并不是你真正想要了解的东西。

我认为这种类型的签名并不完全意味着你认为它的作用:

setOffsetTime::(Ord a,Num b)=>[a]->b

它说的是“如果你给我一个
[a]
类型的值,对于任何
a
类型,你选择它是
Ord
类型类的成员,我会给你一个
b
类型的值,对于你选择它是
Num
类型类的成员的任何
b
。调用方可以选择每次调用
setOffsetTime
时使用的特定类型
a
b

因此,尝试返回类型为
Int
(或
Float
,或任何特定类型)的值是没有意义的
Int
确实是type类
Num
的成员,但它不是type类
Num
的任何成员。根据该类型签名,我应该能够创建一个您从未见过的全新的
Num
实例,从您的模块导入
setOffsetTime
,并调用它以获取我的新类型的值

要获得可接受的返回值,只能使用同样返回任意
Num
的函数。不能使用任何特定具体类型的函数


存在类型本质上是一种机制,允许被调用方选择类型变量的值(然后,无论类型是什么,都必须写入调用方才能工作),但这并不是你在学习的时候真正想做的事情。

只是一句话:在
setOffsetTime
的第二个等式中,你明确声明
read x
的结果应该是
Int
。这立即意味着您函数的结果类型是
Int
,而不是更一般的
b
<